"use client";

import React, { useCallback, useRef, useState, useEffect } from "react";
import Select from "react-select";
import AsyncSelect from "react-select/async";
import toast from "react-hot-toast";
import ui from "./BatchForm.module.css";
import { fetchApi } from "@/lib/api/http";
import {
  getClientsPagedAll,
  getClientDetails,
  searchClientExact,
} from "@/lib/api/clients.api";
import {
  mapClientsToSearchRows,
  groupDuplicateClients,
  normalizeCompanyKey,
  displayCompanyName,
} from "@/lib/api/mappers/clients.mappers";
import type { ClientSearchRow } from "@/lib/api/types/clients.types";
import {
  createBatchAuditRequest,
  getAvailableSlots,
  AUDIT_REQUESTS_API_BASE_URL,
} from "@/lib/api/audit-request.api";
import type { AvailableSlotsResponse } from "@/lib/api/types/audit-request.types";
import type {
  CertificationType,
  AuditMode,
  ClientGroup,
  BatchClientPayload,
  CreateBatchAuditRequestPayload,
  AuditRequestTableRow,
} from "@/lib/api/types/audit-request.types";

// ─── Options ────────────────────────────────────────────────────────────────
const CERTIFICATION_TYPE_OPTIONS: { value: CertificationType; label: string }[] = [
  { value: "INITIAL", label: "Initial Certification" },
  { value: "SURVEILLANCE", label: "Surveillance" },
  { value: "SURVEILLANCE_1", label: "1st Surveillance" },
  { value: "SURVEILLANCE_2", label: "2nd Surveillance" },
  { value: "RECERTIFICATION", label: "Re-Certification" },
  { value: "SURVEILLANCE_RECERT", label: "Surveillance & Re-Certification" },
  { value: "Recertification or renewal", label: "Recertification or Renewal" },
];

const AUDIT_MODE_OPTIONS: { value: AuditMode; label: string }[] = [
  { value: "ONLINE" as AuditMode, label: "Online" },
  { value: "ONSITE" as AuditMode, label: "On-site" },
  { value: "HYBRID" as AuditMode, label: "Hybrid" },
];

const ACCREDITATION_OPTIONS = [
  { value: "ASCB", label: "ASCB" },
  { value: "IAS", label: "IAS" },
  { value: "EIAC", label: "EIAC" },
  { value: "UAF", label: "UAF" },
  { value: "IAF", label: "IAF" },
  { value: "OTHER", label: "Other" },
];

const GROUP_VALUES: ClientGroup[] = ["QRS", "TQS", "QRS_B"];
const groupLabel = (g: ClientGroup) => (g === "QRS_B" ? "QRS-B" : g);

// QRS_B uses the QRS database in the old CRM
const groupToSource = (g: ClientGroup): "QRS" | "TQS" =>
  g === "TQS" ? "TQS" : "QRS";

// 🔹 Search UX — matching is case/symbol-insensitive (lower/UPPER both work).
const MIN_SEARCH_CHARS = 2;

type StdOption = { value: number; label: string };

interface SelectOption {
  value: number | string;
  label: string;
  raw?: ClientSearchRow;
  // 🔹 branch/duplicate rows render greyed out and can't be picked
  isDisabled?: boolean;
}

type AuditeeRow = {
  name: string;
  designation?: string;
  email?: string;
  contact?: string;
};

type ClientCard = BatchClientPayload & {
  _key: string;
  _companyLabel: string;
  _files: File[];
  // 🆕 mandatory typed documents (per client)
  _tradeLicense: File[];
  _prevCert: File[];
};

const emptyAuditee = (): AuditeeRow => ({
  name: "",
  designation: "",
  email: "",
  contact: "",
});

const emptyClient = (): ClientCard => ({
  _key: Math.random().toString(36).slice(2),
  _companyLabel: "",
  company_id: undefined,
  company_name: "",
  company_source: "Client",
  client_ref_id: undefined,
  auditee_name: "",
  auditee_contact: "",
  auditee_email: "",
  auditees: [emptyAuditee()],
  standard_ids: [],
  certification_type: "SURVEILLANCE_1",
  mode: "ONSITE" as AuditMode,
  proposed_date: "",
  proposed_time: "10:00:00",
  location: "",
  scope_of_work: "",        // 🆕
  previous_cert_no: "",     // 🆕
  _files: [],
  _tradeLicense: [],        // 🆕
  _prevCert: [],            // 🆕
});

// ─── Upload with progress ────────────────────────────────────────────────────
const uploadFilesWithProgress = (
  requestId: number,
  files: File[],
  onProgress: (pct: number) => void,
  // 🆕 typed mandatory documents — sent under their own form-data keys
  tradeLicense: File[] = [],
  prevCert: File[] = [],
): Promise<void> =>
  new Promise((resolve, reject) => {
    if (!files.length && !tradeLicense.length && !prevCert.length) {
      onProgress(100);
      return resolve();
    }
    const fd = new FormData();
    tradeLicense.forEach((f) => fd.append("trade_license", f));   // 🆕
    prevCert.forEach((f) => fd.append("previous_certificate", f)); // 🆕
    files.forEach((f) => fd.append("files", f));

    const token =
      localStorage.getItem("token") ||
      localStorage.getItem("accessToken") ||
      localStorage.getItem("access_token");

    const xhr = new XMLHttpRequest();
    xhr.open(
      "POST",
      `${AUDIT_REQUESTS_API_BASE_URL}/audit-requests/${requestId}/upload-documents`,
    );
    if (token) xhr.setRequestHeader("Authorization", `Bearer ${token}`);

    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable)
        onProgress(Math.round((e.loaded / e.total) * 100));
    };
    xhr.onload = () =>
      xhr.status >= 200 && xhr.status < 300
        ? (onProgress(100), resolve())
        : reject(new Error(`Upload failed (${xhr.status})`));
    xhr.onerror = () => reject(new Error("Upload failed (network error)"));
    xhr.send(fd);
  });

// ─── Time helpers ────────────────────────────────────────────────────────────
const toTimeInput = (t: string): string => (t ? t.slice(0, 5) : "");
const toDbTime = (t: string): string =>
  t ? (t.length === 5 ? `${t}:00` : t) : "10:00:00";

const selectPortal = {
  menuPortalTarget:
    typeof document !== "undefined" ? document.body : undefined,
  styles: { menuPortal: (base: any) => ({ ...base, zIndex: 3000 }) },
};

interface Props {
  standards: StdOption[];
  onClose: () => void;
  onSuccess: () => void;
  CompanySearch?: React.ComponentType<any>;
  editingRow?: any | null;
}

export default function BatchAuditRequestForm({
  standards,
  onClose,
  onSuccess,
  CompanySearch,
  editingRow,
}: Props) {
  const [group, setGroup] = useState<ClientGroup>("QRS" as ClientGroup);
  const [accreditation, setAccreditation] = useState("ASCB");
  const [sharedRemarks, setSharedRemarks] = useState("");

  const [clients, setClients] = useState<ClientCard[]>([emptyClient()]);
  const [submitting, setSubmitting] = useState(false);
  const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({});
  const [phase, setPhase] = useState<"idle" | "creating" | "uploading">("idle");
  const [fetchingDetails, setFetchingDetails] = useState<Record<string, boolean>>({});

  const fileInputs = useRef<Record<string, HTMLInputElement | null>>({});
  // 🆕 Load standards internally so edit mode always has them
  const [loadedStandards, setLoadedStandards] = useState<StdOption[]>([]);
  const [existingDocs, setExistingDocs] = useState<any[]>([]);
  const isEdit = !!editingRow;
  const FILE_ORIGIN = (process.env.NEXT_PUBLIC_API_URL || "").replace(/\/api\/?$/, "");
  React.useEffect(() => {
    fetchApi<any>(`${AUDIT_REQUESTS_API_BASE_URL}/standards`)
      .then((res: any) => {
        const list = Array.isArray(res) ? res : (res?.data ?? []);
        setLoadedStandards(list.map((s: any) => ({ value: s.id, label: s.name })));
      })
      .catch(() => { });
  }, []);
  const allStandards = loadedStandards.length > 0 ? loadedStandards : standards;

  // 🆕 ── Slot system state ───────────────────────────────────────────────
  const [slotData, setSlotData] = useState<AvailableSlotsResponse | null>(null);
  const [slotsLoading, setSlotsLoading] = useState(false);

  // 🆕 ── Fetch available slots when form mounts ──────────────────────────
  useEffect(() => {
    setSlotsLoading(true);
    getAvailableSlots()
      .then((data) => setSlotData(data))
      .catch((err) => {
        console.error("[SLOTS] Failed to load available slots:", err);
        setSlotData(null);
      })
      .finally(() => setSlotsLoading(false));
  }, []);

  // 🆕 PRE-FILL FORM WHEN EDITING
  useEffect(() => {
    if (!editingRow) return;
    fetchApi(`${AUDIT_REQUESTS_API_BASE_URL}/audit-requests/${editingRow.id}`)
      .then((r: any) => {
        if (r.client_group) setGroup(r.client_group as ClientGroup);
        if (r.accreditation) setAccreditation(r.accreditation);
        setSharedRemarks(r.marketing_remarks || "");
        setExistingDocs(Array.isArray(r.documents) ? r.documents : []);
        const prefillCard: ClientCard = {
          _key: Math.random().toString(36).slice(2),
          _companyLabel: r.company_name || r.company?.name || "",
          company_id: r.company_id || r.company?.id,
          company_name: r.company_name || r.company?.name || "",
          company_source: r.company_source || "Client",
          client_ref_id: r.client_ref_id,
          auditee_name: r.auditee_name || "",
          auditee_contact: r.auditee_contact || "",
          auditee_email: r.auditee_email || "",
          auditees: Array.isArray(r.auditees) && r.auditees.length > 0 ? r.auditees : [emptyAuditee()],
          standard_ids: Array.isArray(r.standard_ids) ? r.standard_ids : [],
          certification_type: r.certification_type || "SURVEILLANCE_1",
          mode: (r.mode || "ONSITE") as AuditMode,
          proposed_date: r.proposed_date ? new Date(r.proposed_date).toISOString().split("T")[0] : "",
          proposed_time: r.proposed_time || "10:00:00",
          location: r.location || "",
          scope_of_work: r.scope_of_work || "",
          previous_cert_no: r.previous_cert_no || "",
          _files: [],
          _tradeLicense: [],
          _prevCert: [],
        };
        setClients([prefillCard]);
      })
      .catch(() => { });
  }, [editingRow]);
  const setClient = (key: string, patch: Partial<ClientCard>) =>
    setClients((prev) =>
      prev.map((c) => (c._key === key ? { ...c, ...patch } : c)),
    );

  const addAuditee = (key: string) =>
    setClients((prev) =>
      prev.map((c) =>
        c._key === key
          ? { ...c, auditees: [...(c.auditees ?? []), emptyAuditee()] }
          : c,
      ),
    );

  const removeAuditee = (key: string, idx: number) =>
    setClients((prev) =>
      prev.map((c) =>
        c._key === key
          ? { ...c, auditees: (c.auditees ?? []).filter((_, i) => i !== idx) }
          : c,
      ),
    );

  const updateAuditee = (
    key: string,
    idx: number,
    field: "name" | "designation" | "email" | "contact",
    val: string,
  ) =>
    setClients((prev) =>
      prev.map((c) =>
        c._key === key
          ? {
            ...c,
            auditees: (c.auditees ?? []).map((a, i) =>
              i === idx ? { ...a, [field]: val } : a,
            ),
          }
          : c,
      ),
    );

  const addClient = () => setClients((prev) => [...prev, emptyClient()]);
  const removeClient = (key: string) =>
    setClients((prev) =>
      prev.length > 1 ? prev.filter((c) => c._key !== key) : prev,
    );

  // Duplicate a client card — copies auditee, standards, cert type, mode,
  // documents, schedule. The COMPANY is cleared so marketing must pick the
  // correct branch — prevents accidental double-submission for one company.
  const duplicateClient = (key: string) =>
    setClients((prev) => {
      const idx = prev.findIndex((c) => c._key === key);
      if (idx === -1) return prev;
      const src = prev[idx];
      const copy: ClientCard = {
        ...src,
        _key: Math.random().toString(36).slice(2),
        _companyLabel: "",
        company_id: undefined,
        company_name: "",
        company_source: "Client",
        client_ref_id: undefined,
        auditees: (src.auditees ?? []).map((a) => ({ ...a })),
        standard_ids: [...src.standard_ids],
        _files: [...src._files],
        _tradeLicense: [...src._tradeLicense],   // 🆕
        _prevCert: [...src._prevCert],           // 🆕
      };
      return [...prev.slice(0, idx + 1), copy, ...prev.slice(idx + 1)];
    });

  const appendFiles = (key: string, picked: File[]) =>
    setClients((prev) =>
      prev.map((c) =>
        c._key === key
          ? {
            ...c,
            _files: [
              ...c._files,
              ...picked.filter(
                (p) =>
                  !c._files.some(
                    (f) => f.name === p.name && f.size === p.size,
                  ),
              ),
            ],
          }
          : c,
      ),
    );

  // ── 🔒 Scoped client search — debounced (450 ms after typing stops) ──────
  // Partial name, any case. Server returns ONLY the logged-in user's
  // Client rows (no Surveillance). Rows are grouped per real company:
  // ONE selectable option (best record), branch/duplicate variants
  // rendered DISABLED below it.
  const searchDebounce = useRef<ReturnType<typeof setTimeout> | null>(null);

  const runClientSearch = useCallback(
    async (q: string): Promise<SelectOption[]> => {
      try {
        const source = groupToSource(group);
        const res = await searchClientExact(q, source);
        const rows = (res.rows ?? []) as any[];

        const qKey = normalizeCompanyKey(q);
        const groups = groupDuplicateClients(rows);
        const rankOf = (g: { primary: { company_name: string | null } }) => {
          const key = normalizeCompanyKey(g.primary.company_name);
          if (key === qKey) return 0;
          if (key.startsWith(qKey)) return 1;
          return 2;
        };
        groups.sort((a, b) => rankOf(a) - rankOf(b));

        const options: SelectOption[] = [];
        for (const g of groups.slice(0, 8)) {
          const p = mapClientsToSearchRows([g.primary])[0];
          options.push({
            value: p.id,
            label:
              displayCompanyName(p.company_name) +
              (p.Address ? ` — ${p.Address}` : "") +
              `  ·  ${p.client_type}`,
            raw: p,
          });
          // 🔹 branch / duplicate rows — visible, greyed, NOT selectable
          g.duplicates.forEach((d, di) => {
            options.push({
              value: `dup-${d.client_type}-${d.id}-${di}`,
              label: `↳ ${(d.company_name ?? "").trim()} — branch/duplicate (select the main record above)`,
              isDisabled: true,
            });
          });
        }

        // 🔹 popup only after a pause AND from 3 typed characters —
        // never letter by letter
        if (options.length === 0 && q.length >= 3) {
          toast.error(
            "Client not found — enter the full Company name as per the Trade License.",
            { id: "client-search-miss" },
          );
        } else {
          toast.dismiss("client-search-miss");
        }

        return options;
      } catch {
        return [];
      }
    },
    [group],
  );

  const searchCompanies = useCallback(
    (input: string): Promise<SelectOption[]> =>
      new Promise((resolve) => {
        const q = input.trim();
        if (q.length < MIN_SEARCH_CHARS) return resolve([]);
        if (searchDebounce.current) clearTimeout(searchDebounce.current);
        searchDebounce.current = setTimeout(
          () => runClientSearch(q).then(resolve),
          450,
        );
      }),
    [runClientSearch],
  );

  // ── Pick company → auto-fill details from the old CRM ─────────────────────
  const handleCompanyPick = async (key: string, opt: SelectOption | null) => {
    if (!opt) {
      setClient(key, {
        _companyLabel: "",
        company_id: undefined,
        company_name: "",
        company_source: "Client",
        client_ref_id: undefined,
      });
      return;
    }

    // 🔹 duplicates are disabled in the menu, but guard anyway
    if (opt.isDisabled) return;

    const picked = opt.raw ?? null;
    setClient(key, {
      _companyLabel: opt.label,
      company_id: undefined,
      // clean prefill (no "— address" tail) — user edits it to match
      // the Trade License exactly
      company_name:
        displayCompanyName(picked?.company_name ?? "") ||
        picked?.company_name ||
        opt.label,
      company_source: picked?.client_type ?? "Client",
      client_ref_id: picked?.id ?? Number(opt.value),
    });

    // 🔹 one notification per selection — fixed id, never stacks
    toast(
      "Please check and verify the Company Name is correct as per the Trade License.",
      { icon: "📋", id: "verify-client-name", duration: 5000 },
    );

    // 🆕 CHANGED — Auditee details are NO LONGER auto-filled from old CRM.
    //              Marketing must enter auditee name/contact/email fresh for
    //              each new audit request. We only auto-fill LOCATION here
    //              (city) as a courtesy, since that's the company's own address.
    try {
      setFetchingDetails((p) => ({ ...p, [key]: true }));

      const source = groupToSource(group);
      const type =
        picked?.client_type === "Surveillance" ? "Surveillance" : "Client";

      const details = await getClientDetails(Number(opt.value), source, type);

      if (details) {
        setClients((prev) =>
          prev.map((c) => {
            if (c._key !== key) return c;

            // ❌ REMOVED — auditee_name, auditee_contact, auditee_email auto-fill
            //             (marketing enters these manually)
            // ❌ REMOVED — auditees[] rows auto-fill (marketing adds via + Add Auditee)
            // ✅ KEPT   — location auto-fill (helpful courtesy, still editable)
            return {
              ...c,
              location: c.location || details.location || "",
            };
          }),
        );
      }
    } catch {
      /* best-effort — user fills manually if CRM lookup fails */
    } finally {
      setFetchingDetails((p) => ({ ...p, [key]: false }));
    }
  };

  // ── Validation ───────────────────────────────────────────────────────────
  const validate = (): string | null => {
    if (!accreditation.trim()) return "Accreditation is required.";
    for (let i = 0; i < clients.length; i++) {
      const c = clients[i];
      const n = i + 1;
      // if (!c.client_ref_id) return `Client ${n}: select a client from the list.`;
      if (!c.company_name.trim())
        return `Client ${n}: client name cannot be empty — enter it as per the Trade License.`;
      if (!c.standard_ids.length)
        return `Client ${n}: select at least one standard.`;
      if (!c.auditee_name.trim()) return `Client ${n}: auditee name is required.`;
      if (!c.auditee_contact.trim()) return `Client ${n}: contact is required.`;
      if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(c.auditee_email))
        return `Client ${n}: a valid auditee email is required.`;
      if (!c.proposed_date) return `Client ${n}: proposed date is required.`;
      if (!c.proposed_time) return `Client ${n}: proposed time is required.`;
      if (!c.location.trim()) return `Client ${n}: location is required.`;
      // 🆕 typed mandatory documents — mandatory for create, optional for edit
      if (!isEdit) {
        if (!c._tradeLicense.length)
          return `Client ${n}: attach the Trade License.`;
        if (c.certification_type !== "INITIAL" && !c._prevCert.length)
          return `Client ${n}: attach the Previous Certificate (required for this certification type).`;
      }
    }
    return null;
  };

  // ── Submit ───────────────────────────────────────────────────────────────
  const handleSubmit = async (e?: React.FormEvent) => {
    e?.preventDefault();
    const v = validate();
    if (v) return toast.error(v);

    setSubmitting(true);
    setPhase("creating");
    setUploadProgress({});
    try {
      // 🔧 EDIT MODE — update instead of create
      if (isEdit && editingRow?.id) {
        const c = clients[0];
        await fetchApi(`${AUDIT_REQUESTS_API_BASE_URL}/audit-requests/${editingRow.id}`, {
          method: "PATCH",
          body: JSON.stringify({
            company_name: c.company_name.trim(),
            company_source: c.company_source,
            client_ref_id: c.client_ref_id,
            auditee_name: c.auditee_name.trim(),
            auditee_contact: c.auditee_contact.trim(),
            auditee_email: c.auditee_email.trim(),
            auditees: (c.auditees ?? []).filter((a: any) => a.name.trim()).map((a: any) => ({
              name: a.name.trim(), designation: a.designation?.trim() || undefined,
              email: a.email?.trim() || undefined, contact: a.contact?.trim() || undefined,
            })),
            standard_ids: c.standard_ids,
            certification_type: c.certification_type,
            mode: c.mode,
            scope_of_work: c.scope_of_work?.trim() || undefined,
            previous_cert_no: c.previous_cert_no?.trim() || undefined,
            proposed_date: c.proposed_date,
            proposed_time: toDbTime(c.proposed_time),
            location: c.location.trim(),
            accreditation: accreditation.trim(),
            client_group: group,
            marketing_remarks: sharedRemarks.trim() || undefined,
          }),
        });
        if (c._tradeLicense.length || c._prevCert.length || c._files.length) {
          setPhase("uploading");
          await uploadFilesWithProgress(editingRow.id, c._files,
            (pct) => setUploadProgress({ [c._key]: pct }),
            c._tradeLicense, c._prevCert,
          ).catch(() => toast.error("Documents failed to upload."));
        }
        toast.success("Audit request updated successfully.");
        onSuccess();
        onClose();
        return;
      }

      // ── CREATE MODE (original code — unchanged) ──
      const payload: CreateBatchAuditRequestPayload = {
        client_group: group,
        accreditation: accreditation.trim(),
        marketing_remarks: sharedRemarks.trim() || undefined,
        clients: clients.map((c) => ({
          company_name: c.company_name.trim(),
          company_source: c.company_source,
          client_ref_id: c.client_ref_id,
          auditee_name: c.auditee_name.trim(),
          auditee_contact: c.auditee_contact.trim(),
          auditee_email: c.auditee_email.trim(),
          auditees: (c.auditees ?? [])
            .filter((a) => a.name.trim())
            .map((a: any) => ({
              name: a.name.trim(),
              designation: a.designation?.trim() || undefined,
              email: a.email?.trim() || undefined,
              contact: a.contact?.trim() || undefined,
            })),
          standard_ids: c.standard_ids,
          certification_type: c.certification_type,
          mode: c.mode,
          scope_of_work: c.scope_of_work?.trim() || undefined,        // 🆕
          previous_cert_no: c.previous_cert_no?.trim() || undefined,  // 🆕
          proposed_date: c.proposed_date,
          proposed_time: toDbTime(c.proposed_time),
          location: c.location.trim(),
        })),
      };

      const result = await createBatchAuditRequest(payload);

      setPhase("uploading");
      let anyFailed = false;

      await Promise.all(
        result.created.map((r) => {
          const key = clients[r.index]?._key ?? String(r.id);
          return uploadFilesWithProgress(
            r.id,
            clients[r.index]?._files ?? [],
            (pct) => setUploadProgress((prev) => ({ ...prev, [key]: pct })),
            clients[r.index]?._tradeLicense ?? [],   // 🆕
            clients[r.index]?._prevCert ?? [],       // 🆕
          ).catch((err) => {
            anyFailed = true;
            console.warn(`Upload failed for request #${r.id}:`, err);
            toast.error(`Documents failed to upload for ${r.company_name}`);
            setUploadProgress((prev) => ({ ...prev, [key]: -1 }));
          });
        }),
      );

      if (anyFailed) {
        toast(
          "Requests were created, but some documents failed to upload. Re-attach them via Edit.",
          { icon: "⚠️" },
        );
      } else {
        toast.success(
          `${clients.length} audit request${clients.length > 1 ? "s" : ""} submitted.`,
        );
      }
      onSuccess();
      onClose();
    } catch (err: any) {
      toast.error(err?.message || "Something went wrong creating the batch.");
    } finally {
      setSubmitting(false);
      setPhase("idle");
    }
  };

  return (
    <div className={ui.page}>
      {/* ══ Top bar ═══════════════════════════════════════════════════════ */}
      <div className={ui.topbar}>
        <div className={ui.topbarLeft}>
          <button
            type="button"
            className={ui.backBtn}
            onClick={onClose}
            disabled={submitting}
            aria-label="Back"
          >
            ←
          </button>
          <div>
            <h1 className={ui.pageTitle}>New Batch Audit Request</h1>
            <p className={ui.pageSub}>
              One request is created per client · {clients.length} client
              {clients.length > 1 ? "s" : ""} added
            </p>
          </div>
        </div>
        <div className={ui.topbarActions}>
          <button
            type="button"
            className={ui.btnGhost}
            onClick={onClose}
            disabled={submitting}
          >
            Cancel
          </button>
          <button
            type="button"
            className={ui.btnPrimary}
            onClick={() => handleSubmit()}
            disabled={submitting}
          >
            {submitting
              ? phase === "creating"
                ? "Creating requests…"
                : "Uploading documents…"
              : `Submit ${clients.length} Request${clients.length > 1 ? "s" : ""}`}
          </button>
        </div>
      </div>

      {/* ══ Content ═══════════════════════════════════════════════════════ */}
      <div className={ui.content}>
        <form onSubmit={handleSubmit}>
          {/* ── Step 1 · Shared scope ─────────────────────────────────────── */}
          <div className={ui.card}>
            <div className={ui.cardHead}>
              <div className={ui.cardHeadLeft}>
                <span className={ui.stepBadge}>1</span>
                <div>
                  <p className={ui.cardTitle}>Shared Scope</p>
                  <p className={ui.cardHint}>
                    These settings apply to every client in this batch
                  </p>
                </div>
              </div>
            </div>
            <div className={ui.cardBody}>
              <div className={ui.grid}>
                <div className={`${ui.field} ${ui.half}`}>
                  <label className={ui.req}>Group</label>
                  <div className={ui.groupToggle}>
                    {GROUP_VALUES.map((g) => (
                      <button
                        key={g}
                        type="button"
                        className={`${ui.groupBtn} ${group === g ? ui.groupBtnActive : ""}`}
                        onClick={() => setGroup(g)}
                      >
                        {groupLabel(g)}
                        {group === g && (
                          <span className={ui.groupCheck}>✓</span>
                        )}
                      </button>
                    ))}
                  </div>
                  <div className={ui.helper}>
                    Client search looks in the {groupToSource(group)} database
                  </div>
                </div>

                <div className={`${ui.field} ${ui.half}`}>
                  <label className={ui.req}>Accreditation</label>
                  <Select
                    classNamePrefix="rselect"
                    options={ACCREDITATION_OPTIONS}
                    value={
                      ACCREDITATION_OPTIONS.find(
                        (o) => o.value === accreditation,
                      ) ?? null
                    }
                    onChange={(opt) =>
                      setAccreditation((opt?.value as string) ?? "ASCB")
                    }
                    {...selectPortal}
                  />
                </div>

                <div className={ui.full}>
                  <label className={ui.label}>Marketing Remarks</label>
                  <textarea
                    className={ui.textarea}
                    rows={2}
                    value={sharedRemarks}
                    onChange={(e) => setSharedRemarks(e.target.value)}
                    placeholder="Any shared context for the coordinator…"
                    maxLength={1000}
                  />
                  <div className={ui.helper}>Applies to every client</div>
                </div>
              </div>
            </div>
          </div>

          {/* ── Client cards ──────────────────────────────────────────────── */}
          {clients.map((c, i) => (
            <div key={c._key} className={ui.card}>
              <div className={ui.cardHead}>
                <div className={ui.cardHeadLeft}>
                  <span className={`${ui.stepBadge} ${ui.clientBadge}`}>
                    {i + 1}
                  </span>
                  <div>
                    <p className={ui.cardTitle}>
                      {c.company_name || `Client ${i + 1}`}
                    </p>
                    <p className={ui.cardHint}>
                      {c.standard_ids.length} standard
                      {c.standard_ids.length !== 1 ? "s" : ""} ·{" "}
                      {c._files.length} document
                      {c._files.length !== 1 ? "s" : ""}
                      {fetchingDetails[c._key] && " · fetching client details…"}
                    </p>
                  </div>
                </div>
                <div style={{ display: "flex", gap: 8, flexShrink: 0 }}>
                  <button
                    type="button"
                    className={ui.duplicateBtn}
                    onClick={() => duplicateClient(c._key)}
                    disabled={submitting}
                    title="Copy this client for another branch — then pick the company and adjust date/time"
                  >
                    ⧉ Duplicate
                  </button>
                  {clients.length > 1 && (
                    <button
                      type="button"
                      className={ui.removeClientBtn}
                      onClick={() => removeClient(c._key)}
                      disabled={submitting}
                    >
                      Remove
                    </button>
                  )}
                </div>
              </div>

              <div className={ui.cardBody}>
                <div className={ui.grid}>
                  <div className={ui.full}>
                    <label className={ui.label}>Client <span style={{ color: "#94a3b8", fontWeight: 400 }}>(optional)</span></label>
                    <AsyncSelect<SelectOption>
                      key={group} /* reset cached options when group changes */
                      classNamePrefix="rselect"
                      cacheOptions
                      defaultOptions={false}
                      loadOptions={searchCompanies}
                      value={
                        c._companyLabel
                          ? {
                            value: c.company_id ?? -1,
                            label: c._companyLabel,
                          }
                          : null
                      }
                      onChange={(opt) =>
                        handleCompanyPick(c._key, opt as SelectOption | null)
                      }
                      placeholder={`Type the company name (min ${MIN_SEARCH_CHARS} chars, any case)…`}
                      noOptionsMessage={({ inputValue }) =>
                        inputValue.trim().length < MIN_SEARCH_CHARS
                          ? `Type at least ${MIN_SEARCH_CHARS} characters`
                          : `Client not found — please enter the full client name as per the Trade License`
                      }
                      loadingMessage={() => "Searching…"}
                      isClearable
                      isOptionDisabled={(o) => !!(o as SelectOption).isDisabled}
                      {...selectPortal}
                    />
                    <div className={ui.helper} style={{ color: "#64748b" }}>
                      Can&apos;t find the client? Leave this and type the name below.
                    </div>
                  </div>

                  {/* 🆕 Editable client name — user corrects it to match
                      the Trade License. Sent as company_name on submit. */}
                  {(
                    <div className={ui.full}>
                      <label className={`${ui.label} ${ui.req}`}>
                        Client Name (as per Trade License)
                      </label>
                      <input
                        type="text"
                        className={ui.input}
                        value={c.company_name}
                        onChange={(e) =>
                          setClient(c._key, { company_name: e.target.value })
                        }
                        placeholder="Type the client name exactly as written on the Trade License"
                      />
                      <div className={ui.helper} style={{ color: "#b45309" }}>
                        ⚠ Please check and verify the Company name is correct as
                        per the Trade License before continuing.
                      </div>
                    </div>
                  )}

                  <div className={ui.full}>
                    <label className={`${ui.label} ${ui.req}`}>Standards</label>
                    <Select
                      classNamePrefix="rselect"
                      isMulti
                      options={allStandards}
                      value={allStandards.filter((o) =>
                        c.standard_ids.includes(o.value),
                      )}
                      onChange={(opts) =>
                        setClient(c._key, {
                          standard_ids: (opts ?? []).map((o: any) => o.value),
                        })
                      }
                      placeholder="Pick one or more standards (e.g., ISO 9001:2015)"
                      {...selectPortal}
                    />
                  </div>

                  <div className={`${ui.field} ${ui.full}`}>
                    <label className={ui.req}>Certification Type</label>
                    <Select
                      classNamePrefix="rselect"
                      options={CERTIFICATION_TYPE_OPTIONS}
                      value={CERTIFICATION_TYPE_OPTIONS.find(
                        (o) => o.value === c.certification_type,
                      )}
                      onChange={(o) =>
                        o &&
                        setClient(c._key, { certification_type: o.value })
                      }
                      isSearchable={false}
                      {...selectPortal}
                    />
                  </div>

                  {/* 🆕 Scope of Work — FULL WIDTH row of its own */}
                  <div className={ui.full}>
                    <label className={`${ui.label} ${ui.req}`}>
                      Scope of Work
                    </label>
                    <textarea
                      className={ui.textarea}
                      rows={2}
                      value={c.scope_of_work ?? ""}
                      onChange={(e) =>
                        setClient(c._key, { scope_of_work: e.target.value })
                      }
                      placeholder="e.g., Manufacturing of wooden furniture and interior fit-out works"
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label>Previous Certificate No.</label>
                    <input
                      type="text"
                      className={ui.input}
                      value={c.previous_cert_no ?? ""}
                      onChange={(e) =>
                        setClient(c._key, { previous_cert_no: e.target.value })
                      }
                      placeholder="e.g., QRS-14023-QM"
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Audit Mode</label>
                    <Select
                      classNamePrefix="rselect"
                      options={AUDIT_MODE_OPTIONS}
                      value={AUDIT_MODE_OPTIONS.find(
                        (o) => o.value === c.mode,
                      )}
                      onChange={(o) =>
                        o && setClient(c._key, { mode: o.value })
                      }
                      isSearchable={false}
                      {...selectPortal}
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Auditee Name</label>
                    <input
                      type="text"
                      className={ui.input}
                      value={c.auditee_name}
                      onChange={(e) =>
                        setClient(c._key, { auditee_name: e.target.value })
                      }
                      placeholder="e.g., Mr. Azhar K Mohamed"
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Contact Number</label>
                    <input
                      type="text"
                      className={ui.input}
                      value={c.auditee_contact}
                      onChange={(e) =>
                        setClient(c._key, { auditee_contact: e.target.value })
                      }
                      placeholder="e.g., +971 56 367 9416"
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Auditee Email</label>
                    <input
                      type="email"
                      className={ui.input}
                      value={c.auditee_email}
                      onChange={(e) =>
                        setClient(c._key, { auditee_email: e.target.value })
                      }
                      placeholder="contact@company.com"
                    />
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Location Details</label>
                    <input
                      type="text"
                      className={ui.input}
                      value={c.location}
                      onChange={(e) =>
                        setClient(c._key, { location: e.target.value })
                      }
                      placeholder="e.g., Dubai & Sharjah, UAE"
                    />
                  </div>

                  <div className={ui.full}>
                    <label className={ui.label}>Auditees / Attendees</label>
                    <div
                      style={{
                        display: "flex",
                        flexDirection: "column",
                        gap: 8,
                      }}
                    >
                      {(c.auditees ?? []).map((a: any, ai) => (
                        <div key={ai} className={ui.auditeeRow}>
                          <input
                            className={ui.input}
                            placeholder="Name *"
                            value={a.name}
                            onChange={(e) =>
                              updateAuditee(c._key, ai, "name", e.target.value)
                            }
                          />
                          <input
                            className={ui.input}
                            placeholder="Designation"
                            value={a.designation ?? ""}
                            onChange={(e) =>
                              updateAuditee(
                                c._key,
                                ai,
                                "designation",
                                e.target.value,
                              )
                            }
                          />
                          <input
                            className={ui.input}
                            type="email"
                            placeholder="Email (optional)"
                            value={a.email ?? ""}
                            onChange={(e) =>
                              updateAuditee(c._key, ai, "email", e.target.value)
                            }
                          />
                          <input
                            className={ui.input}
                            placeholder="Contact (optional)"
                            value={a.contact ?? ""}
                            onChange={(e) =>
                              updateAuditee(
                                c._key,
                                ai,
                                "contact",
                                e.target.value,
                              )
                            }
                          />
                          {(c.auditees?.length ?? 0) > 1 && (
                            <button
                              type="button"
                              className={ui.iconBtnDanger}
                              onClick={() => removeAuditee(c._key, ai)}
                              aria-label="Remove auditee"
                            >
                              ✕
                            </button>
                          )}
                        </div>
                      ))}
                      <button
                        type="button"
                        className={ui.addRowBtn}
                        onClick={() => addAuditee(c._key)}
                      >
                        + Add Auditee
                      </button>
                    </div>
                    <div className={ui.helper}>
                      ⚠️ <strong>Please enter auditee details manually</strong> — these are
                      no longer auto-filled from the old CRM. For <strong>multiple
                        auditees</strong>, click <strong>+ Add Auditee</strong> above for
                      each additional person (email and contact are optional).
                      These names print on the attendance sheet.
                    </div>
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.req}>Proposed Date</label>

                    {editingRow ? (
                      <input
                        type="date"
                        className={ui.input}
                        value={c.proposed_date}
                        onChange={(e) => setClient(c._key, { proposed_date: e.target.value })}
                      />
                    ) : slotsLoading ? (
                      <div style={{ padding: "6px 0", fontSize: 13, color: "#888" }}>Loading slots…</div>
                    ) : slotData && slotData.dates?.length > 0 ? (
                      <div style={{ display: "grid", gridTemplateColumns: `repeat(${slotData.dates.length}, 1fr)`, gap: 6 }}>
                        {slotData.dates.map((slot) => {
                          const isFull = slot.status === "full";
                          const isSelected = c.proposed_date === slot.date;
                          const dateObj = new Date(slot.date + "T00:00:00");
                          const pct = Math.round((slot.booked / slotData.max_per_day) * 100);
                          return (
                            <div
                              key={slot.date}
                              onClick={() => !isFull && setClient(c._key, { proposed_date: slot.date })}
                              style={{
                                border: isSelected ? "1.5px solid #2563eb" : isFull ? "1px solid #f3f4f6" : "1px solid #e5e7eb",
                                borderRadius: 8,
                                padding: "6px 4px",
                                textAlign: "center",
                                cursor: isFull ? "not-allowed" : "pointer",
                                background: isSelected ? "#eff6ff" : isFull ? "#fafafa" : "#fff",
                                opacity: isFull ? 0.5 : 1,
                                boxShadow: isSelected ? "0 0 0 2px rgba(37,99,235,0.1)" : "none",
                                transition: "all 0.15s",
                              }}
                            >
                              <div style={{ fontSize: 9, fontWeight: 500, color: isSelected ? "#3b82f6" : "#9ca3af", textTransform: "uppercase", letterSpacing: 0.3 }}>
                                {dateObj.toLocaleDateString("en-US", { weekday: "short" })}
                              </div>
                              <div style={{ fontSize: 18, fontWeight: 500, color: isFull ? "#d1d5db" : isSelected ? "#1d4ed8" : "#111827", lineHeight: 1.2, margin: "1px 0" }}>
                                {dateObj.getDate()}
                              </div>
                              <div style={{ fontSize: 10, color: isSelected ? "#3b82f6" : "#6b7280", marginBottom: 4 }}>
                                {dateObj.toLocaleDateString("en-US", { month: "short" })}
                              </div>
                              <div style={{ height: 2, background: "#f3f4f6", borderRadius: 1, overflow: "hidden", margin: "0 3px 3px" }}>
                                <div style={{ height: "100%", borderRadius: 1, width: pct + "%", background: pct >= 100 ? "#ef4444" : pct >= 75 ? "#f59e0b" : "#22c55e" }} />
                              </div>
                              <div style={{ fontSize: 9, fontWeight: 500, color: isFull ? "#ef4444" : "#6b7280" }}>
                                {isFull ? "Full" : slot.available + "/" + slotData.max_per_day}
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    ) : (
                      <input
                        type="date"
                        className={ui.input}
                        value={c.proposed_date}
                        onChange={(e) => setClient(c._key, { proposed_date: e.target.value })}
                        min={new Date().toISOString().split("T")[0]}
                      />
                    )}
                  </div>

                  <div className={`${ui.field} ${ui.half}`}>
                    <label className={ui.label}>Proposed Time</label>
                    <input
                      type="time"
                      className={ui.input}
                      value={toTimeInput(c.proposed_time)}
                      onChange={(e) =>
                        setClient(c._key, {
                          proposed_time: toDbTime(e.target.value),
                        })
                      }
                    />
                  </div>

                  {/* ── Documents ── */}
                  <div className={ui.full}>
                    <label className={`${ui.label} ${ui.req}`}>
                      Supporting Documents
                    </label>

                    {/* 🆕 Previously uploaded documents (edit mode) */}
                    {isEdit && existingDocs.length > 0 && (
                      <div style={{ marginBottom: 12, padding: "10px 14px", background: "#f8fafc", border: "1px solid #e2e8f0", borderRadius: 8 }}>
                        <div style={{ fontSize: 11, fontWeight: 600, color: "#64748b", marginBottom: 8, textTransform: "uppercase", letterSpacing: "0.5px" }}>
                          Previously Uploaded
                        </div>
                        {existingDocs.map((d: any, di: number) => (
                          <div key={di} style={{ display: "flex", alignItems: "center", gap: 8, padding: "6px 0", borderBottom: di < existingDocs.length - 1 ? "1px solid #e2e8f0" : "none" }}>
                            <span style={{ fontSize: 14 }}>
                              {d.doc_type === "trade_license" ? "📜" : d.doc_type === "previous_certificate" ? "🏆" : "📄"}
                            </span>
                            <div style={{ flex: 1, minWidth: 0 }}>
                              <a href={`${FILE_ORIGIN}/${d.path}`} target="_blank" rel="noopener noreferrer" style={{ fontSize: 12, color: "#2563eb", textDecoration: "underline", fontWeight: 500 }}>
                                {d.filename}
                              </a>
                              <span style={{ fontSize: 11, color: "#94a3b8", marginLeft: 6 }}>
                                {d.doc_type === "trade_license" ? "Trade License" : d.doc_type === "previous_certificate" ? "Previous Certificate" : "Other"}
                                {d.size ? ` · ${(d.size / 1024).toFixed(0)} KB` : ""}
                              </span>
                            </div>
                            <button type="button" onClick={() => setExistingDocs((prev: any[]) => prev.filter((_: any, idx: number) => idx !== di))} style={{ fontSize: 11, color: "#dc2626", background: "#fef2f2", border: "1px solid #fecaca", borderRadius: 4, padding: "2px 8px", cursor: "pointer", fontWeight: 600 }}>
                              Remove
                            </button>
                          </div>
                        ))}
                        <div style={{ fontSize: 11, color: "#94a3b8", marginTop: 6 }}>To replace a document, remove it above and attach a new one below.</div>
                      </div>
                    )}
                    {/* 🆕 Mandatory typed documents — per client */}
                    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 8 }}>
                      <div>
                        <label className={isEdit ? ui.label : ui.req}>Trade License</label>
                        <input
                          type="file"
                          multiple
                          accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.zip,.rar"
                          className={ui.input}
                          onChange={(e) =>
                            setClient(c._key, {
                              _tradeLicense: Array.from(e.target.files ?? []),
                            })
                          }
                        />
                        {c._tradeLicense.length > 0 && (
                          <div className={ui.helper} style={{ color: "#0f766e" }}>
                            📎 {c._tradeLicense.map((f) => f.name).join(", ")}
                          </div>
                        )}
                      </div>
                      <div>
                        <label
                          className={
                            isEdit ? ui.label : c.certification_type !== "INITIAL" ? ui.req : undefined
                          }
                        >
                          Previous Certificate
                        </label>
                        <input
                          type="file"
                          multiple
                          accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.zip,.rar"
                          className={ui.input}
                          onChange={(e) =>
                            setClient(c._key, {
                              _prevCert: Array.from(e.target.files ?? []),
                            })
                          }
                        />
                        <div className={ui.helper}>
                          {c.certification_type === "INITIAL"
                            ? "Optional for initial certification"
                            : "Required for this certification type"}
                        </div>
                        {c._prevCert.length > 0 && (
                          <div className={ui.helper} style={{ color: "#0f766e" }}>
                            📎 {c._prevCert.map((f) => f.name).join(", ")}
                          </div>
                        )}
                      </div>
                    </div>

                    <div
                      className={ui.dropzone}
                      onClick={() =>
                        !submitting && fileInputs.current[c._key]?.click()
                      }
                      onDragOver={(e) => e.preventDefault()}
                      onDrop={(e) => {
                        e.preventDefault();
                        if (!submitting)
                          appendFiles(
                            c._key,
                            Array.from(e.dataTransfer.files ?? []),
                          );
                      }}
                    >
                      <div className={ui.dropzoneIcon}>📎</div>
                      <div>
                        <div className={ui.dropzoneText}>
                          Other documents (optional) — drag &amp; drop here,{" "}
                          or <span>click to browse</span>
                        </div>
                        <div className={ui.dropzoneHint}>
                          PDF, JPG, PNG, DOC, ZIP — max 10MB each · new picks
                          are added, never replaced
                        </div>
                      </div>
                    </div>
                    <input
                      ref={(el) => {
                        fileInputs.current[c._key] = el;
                      }}
                      type="file"
                      multiple
                      accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.zip,.rar"
                      className={ui.hiddenInput}
                      onChange={(e) => {
                        appendFiles(c._key, Array.from(e.target.files ?? []));
                        e.target.value = "";
                      }}
                    />

                    {c._files.length > 0 && (
                      <div className={ui.fileList}>
                        {c._files.map((f, fi) => (
                          <div key={fi} className={ui.fileItem}>
                            <span>📄</span>
                            <span className={ui.fileName}>{f.name}</span>
                            <span className={ui.fileSize}>
                              {(f.size / 1024).toFixed(0)} KB
                            </span>
                            {!submitting && (
                              <button
                                type="button"
                                className={ui.fileRemove}
                                onClick={() =>
                                  setClient(c._key, {
                                    _files: c._files.filter(
                                      (_, idx) => idx !== fi,
                                    ),
                                  })
                                }
                                aria-label="Remove file"
                              >
                                ✕
                              </button>
                            )}
                          </div>
                        ))}
                      </div>
                    )}

                    {phase === "uploading" &&
                      uploadProgress[c._key] !== undefined && (
                        <div className={ui.progressWrap}>
                          <div className={ui.progressTrack}>
                            <div
                              className={`${ui.progressFill} ${uploadProgress[c._key] < 0
                                ? ui.progressFillError
                                : uploadProgress[c._key] >= 100
                                  ? ui.progressFillDone
                                  : ""
                                }`}
                              style={{
                                width: `${uploadProgress[c._key] < 0
                                  ? 100
                                  : uploadProgress[c._key]
                                  }%`,
                              }}
                            />
                          </div>
                          <span className={ui.progressLabel}>
                            {uploadProgress[c._key] < 0
                              ? "Failed"
                              : uploadProgress[c._key] >= 100
                                ? "✓ Done"
                                : `${uploadProgress[c._key]}%`}
                          </span>
                        </div>
                      )}
                  </div>
                </div>
              </div>
            </div>
          ))}

          <button
            type="button"
            className={ui.addClientBtn}
            onClick={addClient}
            disabled={submitting}
          >
            + Add Another Client
          </button>

          <div className={ui.note}>
            <span>💡</span>
            <span>
              This creates <strong>{clients.length}</strong> audit request
              {clients.length > 1 ? "s" : ""} — one per client. Use{" "}
              <strong>Duplicate</strong> on a filled card when the same client
              has multiple branches: everything copies, you just pick the
              branch company and adjust the date.
            </span>
          </div>
        </form>
      </div>
    </div>
  );
}