import type {
  CompanyAudit,
  CompanyAuditRow,
} from "@/lib/api/types/companyAudit.types";

function fmtDate(iso: string): string {
  if (!iso || iso.startsWith("1900")) return "—";
  try {
    return new Date(iso)
      .toLocaleDateString("en-GB", {
        day: "2-digit",
        month: "short",
        year: "numeric",
      })
      .replace(/ /g, "-");
  } catch {
    return "—";
  }
}

// ─── Safe string — prevents objects leaking into React render ─────────────────
function safeStr(val: any): string {
  if (val === null || val === undefined) return "—";
  if (typeof val === "string") return val.trim() || "—";
  if (typeof val === "number") return String(val);
  // object with firstName/lastName  e.g. leadAuditor / auditBy
  if (typeof val === "object" && val.firstName)
    return `${val.firstName} ${val.lastName ?? ""}`.trim();
  // object with name  e.g. auditStage / auditType
  if (typeof val === "object" && val.name) return val.name;
  return "—";
}

// ─── Extract auditor from any field shape the API might return ────────────────
function extractAuditorName(raw: any): string {
  // ✅ NEW — Primary source: latest stage's auditBy (where backend now returns it)
  if (Array.isArray(raw?.stages) && raw.stages.length > 0) {
    const sorted = [...raw.stages].sort((a, b) => {
      const da = a?.auditDate ? new Date(a.auditDate).getTime() : 0;
      const db = b?.auditDate ? new Date(b.auditDate).getTime() : 0;
      return db - da; // newest first
    });
    for (const stage of sorted) {
      const u = stage?.auditBy;
      if (u?.firstName) return `${u.firstName} ${u.lastName ?? ""}`.trim();
      if (u?.name) return u.name;
      if (u?.fullName) return u.fullName;
      if (u?.email) return u.email;
      if (typeof u === "string" && u.trim()) return u;
    }
  }

  // ── Legacy fallbacks (unchanged) ────────────────────────────────────────────
  // shape: leadAuditor: { firstName, lastName }
  if (raw?.leadAuditor?.firstName)
    return `${raw.leadAuditor.firstName} ${raw.leadAuditor.lastName ?? ""}`.trim();
  // shape: auditBy: { firstName, lastName }   ← your working project uses this
  if (raw?.auditBy?.firstName)
    return `${raw.auditBy.firstName} ${raw.auditBy.lastName ?? ""}`.trim();
  // shape: flat string
  if (typeof raw?.auditBy === "string" && raw.auditBy) return raw.auditBy;
  if (typeof raw?.audit_by === "string" && raw.audit_by) return raw.audit_by;
  if (typeof raw?.leadAuditor === "string" && raw.leadAuditor)
    return raw.leadAuditor;
  return "—";
}

// ─── Extract audit year from any available field ──────────────────────────────
// ─── Extract audit year — prefer validityPeriod ("2025-2026") as full range ────
function extractAuditYear(raw: any): string {
  // ✅ FIXED — Primary: validityPeriod is the full range like "2025-2026"
  if (typeof raw?.validityPeriod === "string" && raw.validityPeriod.trim()) {
    return raw.validityPeriod.trim();
  }
  // dedicated fields (single year fallback)
  if (raw?.auditYear) return String(raw.auditYear);
  if (raw?.audit_year) return String(raw.audit_year);
  if (raw?.year) return String(raw.year);

  // derive from latest stage's auditDate
  if (Array.isArray(raw?.stages) && raw.stages.length > 0) {
    const withDate = raw.stages.find((s: any) => s?.auditDate);
    if (withDate?.auditDate) {
      try {
        return String(new Date(withDate.auditDate).getFullYear());
      } catch {
        /**/
      }
    }
  }
  // derive from auditDate
  if (raw?.auditDate) {
    try {
      return String(new Date(raw.auditDate).getFullYear());
    } catch {
      /**/
    }
  }
  // derive from created_at / createdAt
  if (raw?.created_at) {
    try {
      return String(new Date(raw.created_at).getFullYear());
    } catch {
      /**/
    }
  }
  if (raw?.createdAt) {
    try {
      return String(new Date(raw.createdAt).getFullYear());
    } catch {
      /**/
    }
  }
  return "—";
}

// ─── Extract created date ─────────────────────────────────────────────────────
function extractCreatedAt(raw: any): string {
  return fmtDate(raw?.created_at ?? raw?.createdAt ?? raw?.date_created ?? "");
}

// ─── Extract audit date — prefer latest stage's auditDate ─────────────────────
function extractAuditDate(raw: any): string {
  // ✅ NEW — latest stage's auditDate (most relevant date)
  if (Array.isArray(raw?.stages) && raw.stages.length > 0) {
    const sorted = [...raw.stages].sort((a, b) => {
      const da = a?.auditDate ? new Date(a.auditDate).getTime() : 0;
      const db = b?.auditDate ? new Date(b.auditDate).getTime() : 0;
      return db - da;
    });
    const latest = sorted.find((s: any) => s?.auditDate);
    if (latest?.auditDate) return fmtDate(latest.auditDate);
  }
  // Fall back to legacy direct field
  return fmtDate(raw?.auditDate);
}

// ─── Extract audit stage — prefer latest stage's stageName ────────────────────
function extractAuditStage(raw: any): string {
  // ✅ NEW — latest stage's stageName (e.g. "Stage 1", "Stage 2")
  if (Array.isArray(raw?.stages) && raw.stages.length > 0) {
    const sorted = [...raw.stages].sort((a, b) => {
      const da = a?.auditDate ? new Date(a.auditDate).getTime() : 0;
      const db = b?.auditDate ? new Date(b.auditDate).getTime() : 0;
      return db - da;
    });
    const latest = sorted.find((s: any) => s?.stageName);
    if (latest?.stageName) return latest.stageName;
  }
  // Fall back to existing fields
  if (raw?.currentStage) return raw.currentStage;
  return safeStr(raw?.auditStage);
}

// ─────────────────────────────────────────────────────────────────────────────
// mapCompanyAuditToRow
// ─────────────────────────────────────────────────────────────────────────────
export function mapCompanyAuditToRow(
  audit: CompanyAudit,
  index: number,
): CompanyAuditRow {
  // 🔍 DEBUG — log first row so you can see EXACT field names from API
  if (index === 0) {
    console.log("═══ [AUDIT RAW ROW 0] ═══", JSON.parse(JSON.stringify(audit)));
  }

  // Cast to any so we can safely read runtime fields not in the TS type
  const raw = audit as any;

  return {
    // ── original fields (unchanged) ──────────────────────────────────────
    sno: index + 1,
    id: audit.id,
    companyName: audit.company?.name ?? "—",
    companyId: audit.company?.id ?? 0,
    auditStage: extractAuditStage(raw), // ✅ now reads latest stage
    auditStageId: raw.auditStage?.id ?? 0,
    leadAuditor: extractAuditorName(raw),
    auditDate: extractAuditDate(raw), // ✅ now reads latest stage
    status: audit.status,
    notes: audit.notes ?? "—",
    findings: audit.findings ?? "—",
    created_at: extractCreatedAt(raw),
    updated_at: fmtDate(audit.updated_at),
    raw: audit,

    // ── NEW fields ────────────────────────────────────────────────────────
    auditBy: extractAuditorName(raw),

    auditType: safeStr(
      raw.auditType ?? raw.audit_type ?? raw.auditStage, // safeStr will extract .name if object
    ),

    auditMode: safeStr(raw.auditMode ?? raw.audit_mode),

    auditYear: extractAuditYear(raw),

    createdAt: extractCreatedAt(raw),
  };
}

// ─────────────────────────────────────────────────────────────────────────────
// mapCompanyAuditsApiResponse
// ─────────────────────────────────────────────────────────────────────────────
export function mapCompanyAuditsApiResponse(
  audits: CompanyAudit[],
): CompanyAuditRow[] {
  return audits.map((a, idx) => mapCompanyAuditToRow(a, idx));
}

// ─────────────────────────────────────────────────────────────────────────────
// mapColumnKeyToValue — all values through safeStr()
// ─────────────────────────────────────────────────────────────────────────────
export function mapColumnKeyToValue(key: string, row: CompanyAuditRow): any {
  const columnMap: Record<string, any> = {
    // ── original keys (unchanged) ────────────────────────────────────────
    id: `#${row.id}`,
    companyName: safeStr(row.companyName),
    auditStage: safeStr(row.auditStage),
    leadAuditor: safeStr(row.leadAuditor),
    auditDate: safeStr(row.auditDate),
    status: safeStr(row.status),
    notes: safeStr(row.notes),
    findings: safeStr(row.findings),
    created_at: safeStr(row.created_at),
    updated_at: safeStr(row.updated_at),

    // ── NEW keys ─────────────────────────────────────────────────────────
    auditBy: safeStr(row.auditBy),
    auditType: safeStr(row.auditType),
    auditMode: safeStr(row.auditMode),
    auditYear: safeStr(row.auditYear),
    createdAt: safeStr(row.createdAt),
  };

  return columnMap[key] !== undefined
    ? columnMap[key]
    : safeStr((row as any)[key]);
}

// ─────────────────────────────────────────────────────────────────────────────
// formatCompanyAuditForExport
// ─────────────────────────────────────────────────────────────────────────────
export function formatCompanyAuditForExport(
  row: CompanyAuditRow,
): Record<string, string | number> {
  return {
    "No.": row.sno,
    "Audit ID": row.id,
    Company: row.companyName,
    "Audit Stage": row.auditStage,
    "Lead Auditor": row.leadAuditor,
    "Audit Date": row.auditDate,
    Status: row.status,
    Notes: row.notes,
    Findings: row.findings,
    Created: row.created_at,
    "Audit By": row.auditBy ?? "—",
    "Audit Type": row.auditType ?? "—",
    "Audit Mode": row.auditMode ?? "—",
    "Audit Year": row.auditYear ?? "—",
  };
}
