// ════════════════════════════════════════════════════════════════════════
// final-closure.api.ts   →   frontend/lib/api/
// GET  /api/previous-nc/closures/list        (list finalized closures)
// DELETE /api/previous-nc/closures/:source/:id  (super-admin: delete + reopen)
// ════════════════════════════════════════════════════════════════════════

import type { NcSource } from '@/lib/api/types/previous-nc.types';

const API_BASE =
  process.env.NEXT_PUBLIC_API_URL?.replace(/\/api$/, '') ||
  process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/api$/, '') ||
  '';

function getAuthToken(): string {
  if (typeof window === 'undefined') return '';
  return (
    localStorage.getItem('access_token') ||
    sessionStorage.getItem('access_token') ||
    localStorage.getItem('token') ||
    localStorage.getItem('authToken') ||
    ''
  );
}

function authHeaders(): HeadersInit {
  const token = getAuthToken();
  return token
    ? { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }
    : { 'Content-Type': 'application/json' };
}

async function handle<T>(res: Response): Promise<T> {
  if (!res.ok) {
    let detail = '';
    try {
      const b = await res.json();
      detail = Array.isArray(b?.message) ? b.message.join('; ') : b?.message || '';
    } catch {}
    throw new Error(
      `${res.status} ${res.statusText}${detail ? ` — ${detail}` : ''}`,
    );
  }
  return res.json();
}

export interface FinalClosureEvidence {
  entry_id: number;
  submitted_docs: string | null;
  evidence_received: string | null;
  document_path: string | null;
  result_accepted: boolean;
}

export interface FinalClosureRow {
  id: number;
  nc_id: number;
  source: NcSource;
  company_name: string | null;
  auditor_name: string | null;
  uploaded_by: string | null;
  evidence_received: string | null;
  evidence_files: FinalClosureEvidence[];
  evidence_count: number;
  signed_copy_path: string | null;
  nc_type: string | null;
  audit_type: string | null;
  closure_date: string | null;
  closed_at: string | null;
  finalized_at: string | null;
  remarks: string | null;
}

export interface FinalClosurePaged {
  rows: FinalClosureRow[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface GetFinalClosuresParams {
  page?: number;
  limit?: number;
  search?: string;
  source?: 'All' | NcSource;
  nc_type?: string;
  audit_type?: string;
  user_name?: string; // matches the NC "All Users" dropdown
  date_from?: string;
  date_to?: string;
}

export async function getFinalClosuresPaged(
  params: GetFinalClosuresParams = {},
): Promise<FinalClosurePaged> {
  const qs = new URLSearchParams();
  if (params.source && params.source !== 'All') qs.set('source', params.source);
  if (params.nc_type && params.nc_type !== 'All') qs.set('nc_type', params.nc_type);
  if (params.audit_type && params.audit_type !== 'All')
    qs.set('audit_type', params.audit_type);
  if (params.search) qs.set('search', params.search);
  if (params.date_from) qs.set('date_from', params.date_from);
  if (params.date_to) qs.set('date_to', params.date_to);
  qs.set('page', String(params.page ?? 1));
  qs.set('limit', String(params.limit ?? 10));

  const url = `${API_BASE}/api/previous-nc/closures/list?${qs.toString()}`;
  const res = await fetch(url, { headers: authHeaders(), cache: 'no-store' });
  const raw = await handle<any>(res);

  const rawRows: any[] = Array.isArray(raw)
    ? raw
    : Array.isArray(raw?.rows)
      ? raw.rows
      : Array.isArray(raw?.data)
        ? raw.data
        : [];

  let rows: FinalClosureRow[] = rawRows.map((r) => ({
    id: r.id ?? r.nc_id,
    nc_id: r.nc_id ?? r.id,
    source: (r.source ?? 'QRS') as NcSource,
    company_name: r.company_name ?? null,
    auditor_name: r.auditor_name ?? null,
    uploaded_by: r.uploaded_by ?? null,
    evidence_received: r.evidence_received ?? null,
    evidence_files: Array.isArray(r.evidence_files) ? r.evidence_files : [],
    evidence_count: Number(r.evidence_count ?? 0),
    signed_copy_path: r.signed_copy_path ?? r.merged_pdf_path ?? null,
    nc_type: r.nc_type ?? null,
    audit_type: r.audit_type ?? null,
    closure_date: r.closure_date ?? null,
    closed_at: r.closed_at ?? null,
    finalized_at: r.finalized_at ?? r.created_at ?? null,
    remarks: r.remarks ?? null,
  }));

  // Client-side filters for fields the backend doesn't filter on yet.
  if (params.audit_type && params.audit_type !== 'All') {
    const want = params.audit_type.trim().toLowerCase();
    rows = rows.filter((r) => (r.audit_type || '').trim().toLowerCase() === want);
  }
  if (params.user_name && params.user_name !== 'all') {
    const want = params.user_name.trim().toLowerCase();
    rows = rows.filter(
      (r) => (r.auditor_name || '').trim().toLowerCase() === want,
    );
  }

  const backendPaginated =
    !Array.isArray(raw) && typeof raw?.total === 'number';
  const page = params.page ?? 1;
  const limit = params.limit ?? 10;

  let pageRows = rows;
  if (!backendPaginated) {
    const start = (page - 1) * limit;
    pageRows = rows.slice(start, start + limit);
  }

  const total = backendPaginated ? raw.total : rows.length;
  return {
    rows: pageRows,
    total,
    page,
    limit,
    totalPages: Math.max(1, Math.ceil(total / limit)),
  };
}

// Super-admin only (enforced server-side). Deletes the closure + merged PDF
// and reopens the NC (findings back to open, closed_at/closed_by cleared).
export async function deleteFinalClosure(
  source: NcSource,
  ncId: number,
): Promise<{ ok: true; reopened: boolean }> {
  const url = `${API_BASE}/api/previous-nc/closures/${source}/${ncId}`;
  const res = await fetch(url, { method: 'DELETE', headers: authHeaders() });
  return handle(res);
}
