import { randomUUID } from "crypto";
import "dotenv/config";
import { ConfigService } from "@nestjs/config";
import { DataSource } from "typeorm";
import { buildDataSourceOptions } from "../src/database/database.config";
import { MonitorRunEntity } from "../src/monitoring/monitor-run.entity";
import { MonitorAgentEntity } from "../src/monitoring/monitor-agent.entity";
import { MonitorTargetEntity } from "../src/monitoring/monitor-target.entity";
import { InspectionRunEntity } from "../src/runs/inspection-run.entity";
import { InspectionTaskEntity } from "../src/tasks/inspection-task.entity";

function buildSteps(siteUrl: string, titleKeyword?: string) {
  const steps = [
    { action: "goto", url: siteUrl, timeoutMs: 20000 },
    { action: "waitForLoadState", value: "domcontentloaded", timeoutMs: 12000 },
    { action: "waitForSelector", selector: "body", timeoutMs: 12000 },
    { action: "assertVisible", selector: "body", timeoutMs: 12000 },
  ] as Array<Record<string, unknown>>;

  if (titleKeyword) {
    steps.push({
      action: "assertText",
      selector: "title",
      contains: titleKeyword,
      timeoutMs: 4000,
    });
  }

  steps.push({ action: "screenshot", value: "landing-page" });
  return JSON.stringify(steps, null, 2);
}

async function seedInspectionData(dataSource: DataSource) {
  const taskRepo = dataSource.getRepository(InspectionTaskEntity);
  const runRepo = dataSource.getRepository(InspectionRunEntity);

  const tasks = [
    {
      id: "gov-portal-main-seed",
      name: "呼和浩特市政府首页巡检",
      siteUrl: "http://www.huhhot.gov.cn/",
      cronExpr: "*/15 * * * *",
      serviceKey: "gov-portal-main",
      titleKeyword: "呼和浩特",
    },
    {
      id: "gov-portal-secondary-seed",
      name: "土默特右旗政府首页巡检",
      siteUrl: "http://www.tmtyq.gov.cn/",
      cronExpr: "*/30 * * * *",
      serviceKey: "gov-portal-secondary",
      titleKeyword: "土默特右旗",
    },
  ];

  for (const item of tasks) {
    let task = await taskRepo.findOne({ where: { id: item.id } });

    if (!task) {
      task = taskRepo.create({
        ...item,
        stepsJson: buildSteps(item.siteUrl, item.titleKeyword),
        preferredExecutor: "browser",
        allowAgentFallback: false,
        status: "enabled",
        lastRunAt: null,
      });
    } else {
      task.name = item.name;
      task.siteUrl = item.siteUrl;
      task.cronExpr = item.cronExpr;
      task.serviceKey = item.serviceKey;
      task.stepsJson = buildSteps(item.siteUrl, item.titleKeyword);
      task.preferredExecutor = "browser";
      task.allowAgentFallback = false;
      task.status = "enabled";
    }

    await taskRepo.save(task);

    const existingRunCount = await runRepo.count({ where: { taskId: task.id } });
    if (existingRunCount === 0) {
      const startedAt = new Date(Date.now() - 10 * 60 * 1000);
      const endedAt = new Date(Date.now() - 9 * 60 * 1000);
      const run = runRepo.create({
        id: randomUUID(),
        taskId: task.id,
        traceId: `seed-${task.serviceKey}`,
        status: "success",
        errorTag: null,
        failureReason: null,
        screenshotUrls: JSON.stringify([]),
        stepLogsJson: JSON.stringify([]),
        pageUrl: task.siteUrl,
        domSummary: null,
        startedAt,
        endedAt,
      });
      await runRepo.save(run);
    }
  }
}

async function seedMonitoringData(dataSource: DataSource) {
  const agentRepo = dataSource.getRepository(MonitorAgentEntity);
  const targetRepo = dataSource.getRepository(MonitorTargetEntity);
  const runRepo = dataSource.getRepository(MonitorRunEntity);

  const agentSeeds = [
    {
      id: "monitor-agent-local-linux-seed",
      name: "本地 Linux Agent 模板",
      agentKey: "linux-demo-agent",
      host: "192.168.1.50",
      platform: "linux" as const,
      status: "disabled" as const,
      monitoringEnabled: false,
      logIngestEnabled: false,
      proactivePushEnabled: false,
    },
    {
      id: "monitor-agent-local-windows-seed",
      name: "本地 Windows Agent",
      agentKey: "local-windows-agent",
      host: "localhost",
      platform: "windows" as const,
      status: "enabled" as const,
      monitoringEnabled: true,
      logIngestEnabled: false,
      proactivePushEnabled: false,
    },
  ];

  for (const item of agentSeeds) {
    let agent = await agentRepo.findOne({ where: { id: item.id } });
    if (!agent) {
      agent = agentRepo.create({
        ...item,
        version: null,
        lastHeartbeatAt: null,
        lastHeartbeatMetaJson: null,
        lastVerifyAt: null,
        lastVerifyStatus: null,
        lastVerifyMessage: null,
      });
    } else {
      agent.name = item.name;
      agent.agentKey = item.agentKey;
      agent.host = item.host;
      agent.platform = item.platform;
      agent.status = item.status;
      agent.monitoringEnabled = item.monitoringEnabled;
      agent.logIngestEnabled = item.logIngestEnabled;
      agent.proactivePushEnabled = item.proactivePushEnabled;
    }
    await agentRepo.save(agent);
  }

  const targets = [
    {
      id: "monitor-http-seed",
      name: "本机 API 健康检查",
      type: "http" as const,
      serviceKey: "sentai-api",
      cronExpr: "*/5 * * * *",
      endpoint: "http://127.0.0.1:3001/health",
      configJson: JSON.stringify(
        {
          timeoutMs: 8000,
          expectedStatus: 200,
          expectedText: "\"ok\":true",
        },
        null,
        2,
      ),
      secretJson: JSON.stringify({}, null, 2),
      status: "enabled" as const,
    },
    {
      id: "monitor-http-blackbox-template-seed",
      name: "HTTP Blackbox 接入模板",
      type: "http" as const,
      serviceKey: "http-blackbox-template",
      cronExpr: "*/10 * * * *",
      endpoint: "http://192.168.1.30:8080/health",
      configJson: JSON.stringify(
        {
          collectionMode: "blackbox",
          blackboxBaseUrl: "http://192.168.1.50:9115",
          blackboxModule: "http_2xx",
          blackboxTarget: "http://192.168.1.30:8080/health",
        },
        null,
        2,
      ),
      secretJson: JSON.stringify({}, null, 2),
      status: "disabled" as const,
    },
    {
      id: "monitor-redis-template-seed",
      name: "Redis 接入模板",
      type: "redis" as const,
      serviceKey: "infra-redis-template",
      cronExpr: "*/10 * * * *",
      endpoint: "192.168.1.10",
      configJson: JSON.stringify(
        {
          tcpHost: "192.168.1.10",
          tcpPort: 6379,
          timeoutMs: 5000,
          redisSections: ["server", "memory", "stats", "replication"],
        },
        null,
        2,
      ),
      secretJson: JSON.stringify(
        {
          authPassword: "",
          sshHost: "",
          sshPort: 22,
          sshUsername: "",
          sshPassword: "",
          logFilePath: "",
          logTailLines: 120,
          logKeyword: "ERROR|Exception|Timeout|Refused",
        },
        null,
        2,
      ),
      status: "disabled" as const,
    },
    {
      id: "monitor-java-template-seed",
      name: "Java 应用接入模板",
      type: "java-app" as const,
      serviceKey: "java-app-template",
      cronExpr: "*/10 * * * *",
      endpoint: "http://192.168.1.20:8080",
      configJson: JSON.stringify(
        {
          javaCollectionMode: "hybrid",
          javaHealthPath: "/actuator/health",
          javaMetricsPath: "/actuator/metrics",
          jmxExporterUrl: "http://192.168.1.20:9404/metrics",
          jmxMetricsPath: "",
          javaRequireHealthCheck: true,
        },
        null,
        2,
      ),
      secretJson: JSON.stringify(
        {
          sshHost: "",
          sshPort: 22,
          sshUsername: "",
          sshPassword: "",
          logFilePath: "/data/logs/app/application.log",
          logTailLines: 150,
          logKeyword: "ERROR|Exception|Timeout|Refused",
        },
        null,
        2,
      ),
      status: "disabled" as const,
    },
  ];

  for (const item of targets) {
    let target = await targetRepo.findOne({ where: { id: item.id } });

    if (!target) {
      target = targetRepo.create({
        ...item,
        lastRunAt: null,
      });
    } else {
      target.name = item.name;
      target.type = item.type;
      target.serviceKey = item.serviceKey;
      target.cronExpr = item.cronExpr;
      target.endpoint = item.endpoint;
      target.configJson = item.configJson;
      target.secretJson = item.secretJson;
      target.status = item.status;
    }

    await targetRepo.save(target);
  }

  const healthTarget = await targetRepo.findOneByOrFail({ id: "monitor-http-seed" });
  const existingRunCount = await runRepo.count({ where: { targetId: healthTarget.id } });

  if (existingRunCount === 0) {
    const startedAt = new Date(Date.now() - 5 * 60 * 1000);
    const endedAt = new Date(Date.now() - 4 * 60 * 1000);
    const run = runRepo.create({
      id: randomUUID(),
      targetId: healthTarget.id,
      traceId: "seed-monitor-http",
      status: "success",
      errorTag: null,
      summary: "API 健康检查通过",
      failureReason: null,
      metricsJson: JSON.stringify({ statusCode: 200 }, null, 2),
      detailsJson: JSON.stringify({ endpoint: healthTarget.endpoint }, null, 2),
      logExcerpt: null,
      resultJsonUrl: null,
      startedAt,
      endedAt,
    });
    await runRepo.save(run);
  }
}

async function main() {
  const configService = new ConfigService(process.env);
  const dataSource = new DataSource(
    buildDataSourceOptions(configService, { synchronize: false }),
  );

  await dataSource.initialize();
  await seedInspectionData(dataSource);
  await seedMonitoringData(dataSource);
  await dataSource.destroy();
}

void main().catch((error) => {
  console.error(error);
  process.exit(1);
});
