import type { ProviderProfile, ProviderProfileValidation, ProviderProfilesResponse } from "@/types";

export interface ProviderProfileRow extends Record<string, unknown> {
  profile: ProviderProfile;
  configured: boolean;
  credentialSource: string;
  credentialHashSuffix: string;
  configHashSuffix: string;
  resourceVersion: string;
  updatedAt: string;
  secretRefText: string;
  bridgeText: string;
  validationStatus: string;
  failureKind: string;
  valuesPrinted: boolean;
  source: Record<string, unknown>;
}

export interface ProviderConfigView {
  profile: string;
  configToml: string;
  configHashSuffix: string;
  valuesPrinted: boolean;
}

export interface ProviderValidationView {
  validationId: string;
  profile: string;
  status: string;
  runId: string;
  commandId: string;
  jobName: string;
  traceId: string;
  failureKind: string;
  terminalStatus: string;
  valuesPrinted: boolean;
}

export function normalizeProviderProfiles(payload: ProviderProfilesResponse | null): ProviderProfileRow[] {
  const record = objectRecord(payload);
  const rows = firstArray(record?.items, record?.profiles, objectRecord(record?.data)?.items, objectRecord(record?.data)?.profiles);
  return rows.map(normalizeProviderProfile).filter((row) => row.profile);
}

export function normalizeProviderProfilePayload(payload: ProviderProfilesResponse | null): ProviderProfileRow | null {
  const record = objectRecord(payload);
  const candidate = objectRecord(record?.data) ?? objectRecord(record?.profile) ?? record;
  if (!candidate) return null;
  const row = normalizeProviderProfile(candidate);
  return row.profile ? row : null;
}

export function normalizeProviderConfig(payload: ProviderProfilesResponse | null, fallbackProfile = ""): ProviderConfigView {
  const record = objectRecord(payload);
  const data = objectRecord(record?.data) ?? record ?? {};
  return {
    profile: text(data.profile ?? record?.profile) || fallbackProfile,
    configToml: text(data.configToml ?? data.toml),
    configHashSuffix: text(data.configHashSuffix ?? data.configHash),
    valuesPrinted: data.valuesPrinted === true || record?.valuesPrinted === true
  };
}

export function normalizeProviderValidation(payload: (ProviderProfilesResponse & ProviderProfileValidation) | null, fallbackProfile = ""): ProviderValidationView {
  const record = objectRecord(payload);
  const data = objectRecord(record?.data) ?? record ?? {};
  const result = objectRecord(data.result);
  const agentRun = objectRecord(data.agentRun ?? result?.agentRun);
  return {
    validationId: text(data.validationId ?? record?.validationId),
    profile: text(data.profile ?? record?.profile) || fallbackProfile,
    status: text(data.status ?? record?.status) || "unknown",
    runId: text(data.runId ?? agentRun?.runId),
    commandId: text(data.commandId ?? agentRun?.commandId),
    jobName: text(data.jobName ?? agentRun?.jobName),
    traceId: text(data.traceId ?? agentRun?.traceId),
    failureKind: text(data.failureKind ?? result?.failureKind ?? objectRecord(data.error)?.code),
    terminalStatus: text(data.terminalStatus ?? result?.terminalStatus),
    valuesPrinted: data.valuesPrinted === true || record?.valuesPrinted === true
  };
}

export function validationComplete(status: string): boolean {
  return ["completed", "failed", "blocked", "timeout", "canceled", "cancelled"].includes(status.toLowerCase());
}

export function mergeProviderRow(rows: ProviderProfileRow[], updated: ProviderProfileRow | null): ProviderProfileRow[] {
  if (!updated) return rows;
  const next = rows.filter((row) => row.profile !== updated.profile);
  next.push(updated);
  return orderProviderProfiles(next);
}

export function orderProviderProfiles(rows: ProviderProfileRow[]): ProviderProfileRow[] {
  const preferred = ["deepseek", "dsflash-go", "codex-api", "minimax-m3"];
  return [...rows].sort((a, b) => {
    const ai = preferred.indexOf(a.profile);
    const bi = preferred.indexOf(b.profile);
    if (ai !== -1 || bi !== -1) return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
    return a.profile.localeCompare(b.profile);
  });
}

function normalizeProviderProfile(value: unknown): ProviderProfileRow {
  const record = objectRecord(value) ?? {};
  const secretRef = objectRecord(record.secretRef);
  const bridge = objectRecord(record.bridge);
  const validation = objectRecord(record.validation ?? record.lastValidation);
  const profile = text(record.profile ?? record.name ?? record.id ?? record.providerProfile);
  return {
    profile,
    configured: booleanValue(record.configured ?? record.ready),
    credentialSource: text(record.credentialSource),
    credentialHashSuffix: text(record.credentialHashSuffix ?? record.keyHashSuffix ?? record.apiKeyHashSuffix),
    configHashSuffix: text(record.configHashSuffix ?? record.configHash),
    resourceVersion: text(record.resourceVersion ?? secretRef?.resourceVersion),
    updatedAt: text(record.updatedAt ?? secretRef?.updatedAt),
    secretRefText: secretRefText(secretRef),
    bridgeText: text(bridge?.route ?? bridge?.serviceUrl ?? record.backendKind ?? record.backend),
    validationStatus: text(validation?.status ?? record.validationStatus),
    failureKind: text(validation?.failureKind ?? record.failureKind),
    valuesPrinted: record.valuesPrinted === true,
    source: record
  };
}

function secretRefText(secretRef: Record<string, unknown> | null): string {
  if (!secretRef) return "-";
  const namespace = text(secretRef.namespace);
  const name = text(secretRef.name);
  const keys = Array.isArray(secretRef.keys) ? secretRef.keys.map((item) => text(item)).filter(Boolean).join(",") : "";
  return [namespace, name].filter(Boolean).join("/") + (keys ? ` [${keys}]` : "");
}

function objectRecord(value: unknown): Record<string, unknown> | null {
  return value && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : null;
}

function firstArray(...values: unknown[]): Record<string, unknown>[] {
  for (const value of values) if (Array.isArray(value)) return value.filter((item): item is Record<string, unknown> => Boolean(objectRecord(item)));
  return [];
}

function text(value: unknown): string {
  return typeof value === "string" ? value.trim() : "";
}

function booleanValue(value: unknown): boolean {
  if (typeof value === "boolean") return value;
  if (typeof value === "string") return ["1", "true", "yes", "ready", "configured"].includes(value.toLowerCase());
  return Boolean(value);
}
