import type BetterSqlite3 from "better-sqlite3";

import type { AdminDiagnosticsResponse, AdminServicesStorageResponse } from "@dada/shared-contracts";

import type { BrowserSupportRelease } from "./browser-support.js";
import type { ManagedStorage } from "./managed-storage.js";
import type { ModelConfigurationService } from "./model-configuration.js";

type AdminService = AdminServicesStorageResponse["services"][number];
const adminServiceIds = ["resend", "amap", "ai_gateway", "worker", "api", "asset_root"] as const;
const forbiddenDiagnosticPatterns = [
  /\b(?:api[_ -]?key|secret|password|credential|authorization|bearer|session[_ -]?token|cookie|prompt|email|token)\b/i,
  /[A-Z]:[\\/](?:Users|Documents|ProgramData|Windows)[\\/]/i,
  /\\\\[^\\\s]+\\[^\s]+/,
  /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i,
  /https?:\/\//i,
];
const safePauseReasons = new Set([
  "asset_manifest_invalid", "asset_root_missing", "asset_root_state_missing", "balance_insufficient", "configured_disabled", "contract_blocked",
  "contract_unverified", "gateway_balance_insufficient", "gateway_paused", "health_check_failed",
  "model_disabled", "provider_unavailable", "quota_exhausted", "service_state_missing", "unknown",
  "worker_degraded", "worker_state_missing", "worker_stopped",
]);

function iso(value: number | string | null | undefined) {
  if (value === null || value === undefined) return null;
  return typeof value === "number" ? new Date(value).toISOString() : value;
}

function tableExists(database: BetterSqlite3.Database, table: string) {
  return Boolean(database.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table));
}

function safeService(
  service_id: AdminService["service_id"],
  status: AdminService["status"],
  impact_scope: AdminService["impact_scope"],
  configured: boolean,
  checked_at: string | null,
  pause_reason: string | null = null,
): AdminService {
  return { checked_at, configured, impact_scope, pause_reason, service_id, status };
}

function safeReason(value: unknown) {
  return typeof value === "string" && safePauseReasons.has(value) ? value : null;
}

function serviceUsage(database: BetterSqlite3.Database, serviceName: string) {
  if (!tableExists(database, "external_service_usage")) return undefined;
  const columns = new Set((database.prepare("PRAGMA table_info(external_service_usage)").all() as Array<{ name: string }>).map((column) => column.name));
  const serviceColumn = columns.has("service_name") ? "service_name" : columns.has("service_id") ? "service_id" : undefined;
  if (!serviceColumn || !columns.has("service_status")) return undefined;
  const row = database.prepare(`SELECT service_status, ${columns.has("checked_at") ? "checked_at" : "NULL AS checked_at"}, ${columns.has("pause_reason") ? "pause_reason" : "NULL AS pause_reason"} FROM external_service_usage WHERE ${serviceColumn} = ? ORDER BY rowid DESC LIMIT 1`).get(serviceName) as { service_status: string; checked_at: number | string | null; pause_reason: string | null } | undefined;
  if (!row) return undefined;
  const status = new Set<AdminService["status"]>(["active", "paused_quota", "paused_provider", "disabled"]).has(row.service_status as AdminService["status"])
    ? row.service_status as AdminService["status"]
    : "degraded";
  return { status, checked_at: iso(row.checked_at), pause_reason: safeReason(row.pause_reason) };
}

function workerStatus(database: BetterSqlite3.Database) {
  if (!tableExists(database, "worker_runtime_state")) return { status: "unavailable" as const, checked_at: null, pause_reason: "worker_state_missing" };
  const row = database.prepare("SELECT status, reason, updated_at FROM worker_runtime_state WHERE singleton = 1").get() as { status: string; reason: string | null; updated_at: number | string | null } | undefined;
  if (!row) return { status: "unavailable" as const, checked_at: null, pause_reason: "worker_state_missing" };
  return {
    status: row.status === "ready" ? "active" as const : row.status === "degraded" ? "degraded" as const : "unavailable" as const,
    checked_at: iso(row.updated_at),
    pause_reason: safeReason(row.reason),
  };
}

export function createAdminServicesStorageProvider(input: {
  database: BetterSqlite3.Database;
  models?: ModelConfigurationService;
  storage?: ManagedStorage;
  assetRoot?: Pick<AdminService, "configured" | "status" | "checked_at" | "pause_reason">;
  clock?: () => number;
}): () => AdminServicesStorageResponse {
  const clock = input.clock ?? Date.now;
  return () => {
    const generatedAt = new Date(clock()).toISOString();
    const resend = serviceUsage(input.database, "resend");
    const amap = serviceUsage(input.database, "amap");
    const worker = workerStatus(input.database);
    const modelRuntime = input.models?.read().models ?? [];
    const unavailableModels = modelRuntime.filter((model) => !model.runtime_availability.available_for_new_jobs);
    const gatewayReason = unavailableModels[0]?.runtime_availability.reason ?? null;
    const storageState = input.storage?.getState();
    const cleanupPendingCount = tableExists(input.database, "file_cleanup_queue")
      ? (input.database.prepare("SELECT COUNT(*) AS count FROM file_cleanup_queue WHERE status IN ('pending', 'failed')").get() as { count: number }).count
      : 0;
    const services: AdminService[] = [
      safeService("resend", resend?.status ?? "unavailable", "authentication", Boolean(resend), resend?.checked_at ?? null, resend?.pause_reason ?? "service_state_missing"),
      safeService("amap", amap?.status ?? "unavailable", "location", Boolean(amap), amap?.checked_at ?? null, amap?.pause_reason ?? "service_state_missing"),
      safeService("ai_gateway", unavailableModels.length > 0 ? "degraded" : modelRuntime.length > 0 ? "active" : "unavailable", "generation", modelRuntime.length > 0, generatedAt, safeReason(gatewayReason)),
      safeService("worker", worker.status, "generation", worker.status !== "unavailable", worker.checked_at, worker.pause_reason),
      safeService("api", "active", "api", true, generatedAt),
      safeService(
        "asset_root",
        input.assetRoot?.status ?? "unavailable",
        "storage",
        input.assetRoot?.configured ?? false,
        input.assetRoot?.checked_at ?? null,
        input.assetRoot?.pause_reason ?? "asset_root_state_missing",
      ),
    ];
    return assertSafeAdminServicesStorage({
      generated_at: generatedAt,
      services,
      storage: {
        capacity_notice_level: storageState?.capacity_notice_level ?? "normal",
        cleanup_pending_count: cleanupPendingCount,
        data_root_ref: "configured_local_data_root",
        hard_limit_bytes: storageState?.hard_limit_bytes ?? 5_368_709_120,
        last_measured_at: storageState?.measured_at ?? null,
        managed_content_bytes: storageState?.managed_content_bytes ?? 0,
        remeasurement_required: storageState?.storage_status === "unavailable",
        status: storageState?.storage_status ?? "unavailable",
        storage_backend: "local_filesystem",
      },
    });
  };
}

function diagnosticText(input: AdminServicesStorageResponse, system: AdminDiagnosticsResponse["system"]) {
  const lines = [
    "Dada P0-A diagnostics",
    `app_version=${system.app_version}`,
    `api_status=${system.api_status}`,
    `worker_status=${system.worker_status}`,
    `storage_status=${input.storage.status}`,
    `capacity_notice_level=${input.storage.capacity_notice_level}`,
    `managed_content_bytes=${input.storage.managed_content_bytes}`,
    `hard_limit_bytes=${input.storage.hard_limit_bytes}`,
    `cleanup_pending_count=${input.storage.cleanup_pending_count}`,
  ];
  for (const service of input.services) lines.push(`service.${service.service_id}=${service.status}`);
  return lines.join("\n");
}

export function createAdminDiagnosticsProvider(input: {
  servicesStorage: () => AdminServicesStorageResponse;
  browserSupportRelease?: BrowserSupportRelease;
  appVersion?: string;
  clock?: () => number;
}): () => AdminDiagnosticsResponse {
  const clock = input.clock ?? Date.now;
  return () => {
    const services = input.servicesStorage();
    const system: AdminDiagnosticsResponse["system"] = {
      api_status: "ready",
      app_version: input.appVersion ?? input.browserSupportRelease?.appVersion ?? "0.0.0",
      browser_support: (input.browserSupportRelease?.browsers ?? []).map((browser) => ({
        brand: browser.brand,
        major: Number.parseInt(browser.fullVersion.split(".")[0] ?? "0", 10),
      })).filter((browser) => Number.isSafeInteger(browser.major) && browser.major > 0),
      worker_status: services.services.find((service) => service.service_id === "worker")?.status === "active"
        ? "ready"
        : services.services.find((service) => service.service_id === "worker")?.status === "unavailable"
          ? "unavailable"
          : "degraded",
    };
    return assertSafeAdminDiagnostics({
      generated_at: new Date(clock()).toISOString(),
      diagnostic_text: diagnosticText(services, system),
      services,
      system,
    });
  };
}

export function assertSafeAdminServicesStorage(input: AdminServicesStorageResponse) {
  const ids = input.services.map((service) => service.service_id);
  if (ids.length !== adminServiceIds.length || new Set(ids).size !== adminServiceIds.length
    || adminServiceIds.some((serviceId) => !ids.includes(serviceId))) {
    throw new Error("admin_service_state_incomplete");
  }
  if (input.services.some((service) => service.pause_reason !== null && !safePauseReasons.has(service.pause_reason))) {
    throw new Error("admin_services_redaction_failed");
  }
  if (forbiddenDiagnosticPatterns.some((pattern) => pattern.test(JSON.stringify(input)))) {
    throw new Error("admin_services_redaction_failed");
  }
  return input;
}

export function assertSafeAdminDiagnostics(input: AdminDiagnosticsResponse) {
  assertSafeAdminServicesStorage(input.services);
  if (forbiddenDiagnosticPatterns.some((pattern) => pattern.test(input.diagnostic_text))) {
    throw new Error("admin_diagnostics_redaction_failed");
  }
  return input;
}
