// ═══════════════════════════════════════════════════════════════════════════════
// ✨ CLIENT PORTAL API - FIXED with correct endpoints
// ═══════════════════════════════════════════════════════════════════════════════

// Get API base URL from environment or use default
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3008/api";

// ✅ Get client portal token from localStorage
function getClientToken(): string {
  if (typeof window === "undefined") return "";
  return localStorage.getItem("clientPortalToken") || "";
}

// ✅ Fetch with automatic token injection
async function clientFetch<T = any>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  const token = getClientToken();
  const headers = new Headers(options.headers || {});

  if (token) {
    headers.set("Authorization", `Bearer ${token}`);
  }
  headers.set("Content-Type", "application/json");

  const response = await fetch(`${API_BASE}${endpoint}`, {
    ...options,
    headers,
  });

  // Handle 401 - token expired
  if (response.status === 401) {
    localStorage.removeItem("clientPortalToken");
    localStorage.removeItem("clientUser");
    if (typeof window !== "undefined") {
      window.location.href = "/client/login";
    }
    throw new Error("Unauthorized - please login again");
  }

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({}));
    throw new Error(
      errorData.message || `API Error: ${response.status} ${response.statusText}`
    );
  }

  return response.json() as Promise<T>;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ✨ CLIENT PORTAL API ENDPOINTS
// ═══════════════════════════════════════════════════════════════════════════════

export const clientPortalApi = {
  // ── Authentication ───────────────────────────────────────────
  // ✅ FIXED: Route to correct endpoint based on whether invite_token exists
  login: async (email: string, inviteToken?: string) => {
    const body: any = { email };
    
    // If they have an invite token, use the token-based login
    if (inviteToken) {
      body.token = inviteToken;
      return clientFetch("/client-portal/login", {
        method: "POST",
        body: JSON.stringify(body),
      });
    }
    
    // Otherwise use email-only login endpoint (sends OTP to email)
    return clientFetch("/client-portal/login-email", {
      method: "POST",
      body: JSON.stringify(body),
    });
  },

  // Verify OTP code
  verifyOtp: async (email: string, otp_code: string) => {
    return clientFetch("/client-portal/verify-otp", {
      method: "POST",
      body: JSON.stringify({
        email,
        otp_code,
      }),
    });
  },

  // Resend OTP
  resendOtp: async (email: string, inviteToken?: string) => {
    const body: any = { email };
    if (inviteToken) {
      body.token = inviteToken;
    }
    return clientFetch("/client-portal/resend-otp", {
      method: "POST",
      body: JSON.stringify(body),
    });
  },

  // 👇 NEW — Refresh access token using the stored refresh token.
  //         Used by useClientAuth to silently renew the 15-min access token
  //         every 13 minutes, so client stays logged in for up to 30 days
  //         without re-entering OTP.
  refreshToken: async (refreshToken: string) => {
    return clientFetch("/client-portal/refresh-token", {
      method: "POST",
      body: JSON.stringify({ refresh_token: refreshToken }),
    });
  },

  // 👇 NEW — Logout (revoke a specific refresh token on the server side).
  //         Called from forceLogout() to invalidate the token so it can't
  //         be reused even if it leaks.
  logout: async (refreshToken: string) => {
    return clientFetch("/client-portal/logout", {
      method: "POST",
      body: JSON.stringify({ refresh_token: refreshToken }),
    });
  },

  // ── Company Data (Protected) ─────────────────────────────────
  // Get company information
  getCompany: async () => {
    return clientFetch("/client-portal/company", {
      method: "GET",
    });
  },

  // Get list of audits
  getAudits: async () => {
    return clientFetch("/client-portal/audits", {
      method: "GET",
    });
  },

  // Get single audit details and progress
  getAudit: async (id: number) => {
    return clientFetch(`/client-portal/audits/${id}/progress`, {
      method: "GET",
    });
  },

  // Get audit report
  getAuditReport: async (id: number) => {
    return clientFetch(`/client-portal/audits/${id}/report`, {
      method: "GET",
    });
  },

  // Get list of certificates
  getCertificates: async () => {
  // 🔍 DEBUG: Check token
  const token = localStorage.getItem("clientPortalToken");
  console.log("🔑 Token in localStorage:", token?.substring(0, 50) + "...");
  
  if (!token) {
    console.error("❌ NO TOKEN FOUND - need to login!");
    return { data: [] };
  }
  
  // 🔍 DEBUG: Decode token to check company_ids
  try {
    const payload = JSON.parse(atob(token.split('.')[1]));
    console.log("📋 Token payload:", payload);
    console.log("📋 company_ids in token:", payload.company_ids);
  } catch (e) {
    console.error("❌ Failed to decode token:", e);
  }
  
  // 🔍 DEBUG: Call API
  console.log("🚀 Calling API: /client-portal/certificates");
  const response = await clientFetch("/client-portal/certificates", {
    method: "GET",
  });
  
  // 🔍 DEBUG: Check response
  console.log("📦 API Response:", response);
  console.log("📦 Response.data length:", response?.data?.length);
  
  return response;
},

  // Get list of branches
  getBranches: async () => {
    return clientFetch("/client-portal/branches", {
      method: "GET",
    });
  },

  // Get list of non-conformities
  getNcs: async () => {
    return clientFetch("/client-portal/ncs", {
      method: "GET",
    });
  },
  // Get rich NC list (with finding counts) — new endpoint
 getNcsList: async () => {
    return clientFetch("/client-portal/ncs/list", {
      method: "GET",
    });
  },

  // Get one NC with its findings
  getNcDetail: async (id: number) => {
    return clientFetch(`/client-portal/ncs/${id}`, {
      method: "GET",
    });
  },
  getTeam: async () => {
  return clientFetch("/client-portal/team", {
    method: "GET",
  });
},
inviteTeamMember: async (email: string) => {
  return clientFetch("/client-portal/team/invite", {
    method: "POST",
    body: JSON.stringify({ email }),
  });
},
};

// ═══════════════════════════════════════════════════════════════════════════════
// ✨ CHECKLIST — documents requested by your auditor
//    Added for the audit checklist flow. GET/POST reuse clientFetch above;
//    upload + document/PDF viewers must NOT use clientFetch because it
//    forces Content-Type: application/json and always response.json() —
//    uploads need multipart FormData (+ XHR progress) and viewers need a
//    binary blob. They still reuse getClientToken() + API_BASE.
// ═══════════════════════════════════════════════════════════════════════════════

export type ClientChecklistItemStatus = "missing" | "uploaded" | "approved" | "rejected";

export interface ClientChecklistItem {
  id: number;
  status: ClientChecklistItemStatus;
  document_path?: string | null;
  document_original_name?: string | null;
  uploaded_at?: string | null;
  rejection_note?: string | null;
  template_item: { item_text: string };
}

export interface ClientChecklist {
  id: number;
  audit_schedule_row_id: number;
  standard_id: number;
  standard?: { id: number; name: string } | null;
  client_notified_at?: string | null;
  client_submitted_at?: string | null;
  completed_at?: string | null;
  client_message?: string | null;
  due_date?: string | null;
  items: ClientChecklistItem[];
}

function clearClientSession() {
  localStorage.removeItem("clientPortalToken");
  localStorage.removeItem("clientUser");
  if (typeof window !== "undefined") window.location.href = "/client/login";
}

/** Checklists the auditor has sent for one of my audits (grouped by standard). */
export async function getClientAuditChecklists(auditId: number): Promise<ClientChecklist[]> {
  const res = await clientFetch<ClientChecklist[] | { data: ClientChecklist[] }>(
    `/client-portal/audits/${auditId}/checklists`,
    { method: "GET" },
  );
  return Array.isArray(res) ? res : (res as any).data || [];
}

/** Upload (or re-upload) one document. XHR so we get real progress %. */
export function uploadChecklistItemDocument(
  itemId: number,
  file: File,
  onProgress?: (pct: number) => void,
): Promise<ClientChecklistItem> {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("POST", `${API_BASE}/client-portal/checklists/items/${itemId}/upload`);
    const token = getClientToken();
    if (token) xhr.setRequestHeader("Authorization", `Bearer ${token}`);
    // NOTE: no Content-Type header — the browser sets the multipart boundary.

    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable && onProgress) onProgress(Math.round((e.loaded / e.total) * 100));
    };
    xhr.onload = () => {
      if (xhr.status === 401) {
        clearClientSession();
        reject(new Error("Unauthorized - please login again"));
        return;
      }
      try {
        const body = JSON.parse(xhr.responseText || "{}");
        if (xhr.status >= 200 && xhr.status < 300) resolve(body);
        else {
          const msg = Array.isArray(body.message) ? body.message.join(", ") : body.message;
          reject(new Error(msg || `Upload failed (${xhr.status})`));
        }
      } catch {
        xhr.status >= 200 && xhr.status < 300
          ? resolve({} as ClientChecklistItem)
          : reject(new Error(`Upload failed (${xhr.status})`));
      }
    };
    xhr.onerror = () => reject(new Error("Network error during upload"));

    const form = new FormData();
    form.append("file", file);
    xhr.send(form);
  });
}

/** My own Submit — allowed only when every item is uploaded. */
export async function clientSubmitChecklist(checklistId: number): Promise<void> {
  await clientFetch(`/client-portal/checklists/${checklistId}/submit`, { method: "POST" });
}

/** View my own uploaded document (binary blob — cannot use clientFetch). */
export async function openClientItemDocument(itemId: number): Promise<void> {
  const token = getClientToken();
  const res = await fetch(`${API_BASE}/client-portal/checklists/items/${itemId}/document`, {
    headers: token ? { Authorization: `Bearer ${token}` } : {},
  });
  if (res.status === 401) {
    clearClientSession();
    throw new Error("Unauthorized - please login again");
  }
  if (!res.ok) throw new Error("Could not load the document.");
  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  window.open(url, "_blank", "noopener");
  setTimeout(() => URL.revokeObjectURL(url), 60_000);
}

/** View the checklist itself as a PDF — the same file attached to the email. */
export async function openClientChecklistPdf(checklistId: number): Promise<void> {
  const token = getClientToken();
  const res = await fetch(`${API_BASE}/client-portal/checklists/${checklistId}/pdf`, {
    headers: token ? { Authorization: `Bearer ${token}` } : {},
  });
  if (res.status === 401) {
    clearClientSession();
    throw new Error("Unauthorized - please login again");
  }
  if (!res.ok) throw new Error("Could not load the checklist PDF.");
  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  window.open(url, "_blank", "noopener");
  setTimeout(() => URL.revokeObjectURL(url), 60_000);
}