"use client";

import React, { useEffect, useState, useCallback, useMemo } from "react";
import toast from "react-hot-toast";
import { fetchApi } from "@/lib/api/http";
import { AppToaster } from "./../../../../../../components/AppToaster";

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3007/api";
const PAGE_SIZE = 10;

interface DuplicateCompany {
  id: number;
  name: string;
  normalized_name: string;
  company_code: string;
  contact_person: string;
  email: string;
  mobile: string;
  city: string;
  client_group: string;
  created_at: string;
  audit_request_count: number;
  branch_count: number;
  portal_user_count: number;
  audit_count: number;
  inquiry_count: number;
}

interface DuplicateGroup {
  normalized_name: string;
  companies: DuplicateCompany[];
}

interface MergeResult {
  kept_id: number;
  removed_id: number;
  removed_name: string;
  moved: Record<string, number>;
}

function calcScore(c: DuplicateCompany): number {
  let s = 0;
  s += c.audit_request_count * 10;
  s += c.audit_count * 10;
  s += c.inquiry_count * 5;
  s += c.branch_count * 3;
  s += c.portal_user_count * 5;
  if (c.contact_person && c.contact_person !== "Unknown") s += 2;
  if (c.email && c.email !== "unknown@example.com") s += 2;
  if (c.mobile && c.mobile !== "0000000000") s += 1;
  if (c.city) s += 1;
  return s;
}

function fmtDate(d: string | null): string {
  if (!d) return "—";
  return new Date(d).toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });
}

export default function MergeDuplicatesPage() {
  const [groups, setGroups] = useState<DuplicateGroup[]>([]);
  const [loading, setLoading] = useState(true);
  const [merging, setMerging] = useState<string | null>(null);
  const [dismissed, setDismissed] = useState<Set<string>>(new Set());
  const [history, setHistory] = useState<any[]>([]);
  const [showHistory, setShowHistory] = useState(false);
  const [expandedGroup, setExpandedGroup] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);

  const fetchDuplicates = useCallback(async () => {
    setLoading(true);
    try {
      const data = await fetchApi<DuplicateGroup[]>(`${API_BASE}/companies/merge/duplicates`);
      setGroups(Array.isArray(data) ? data : []);
    } catch (err: any) {
      toast.error(err?.message || "Failed to load duplicates");
      setGroups([]);
    } finally {
      setLoading(false);
    }
  }, []);

  const fetchHistory = useCallback(async () => {
    try {
      const data = await fetchApi<any[]>(`${API_BASE}/companies/merge/history`);
      setHistory(Array.isArray(data) ? data : []);
    } catch { setHistory([]); }
  }, []);

  useEffect(() => { fetchDuplicates(); fetchHistory(); }, [fetchDuplicates, fetchHistory]);

  const activeGroups = useMemo(() => {
    let filtered = groups.filter((g) => !dismissed.has(g.normalized_name));
    if (search.trim()) {
      const q = search.toLowerCase().trim();
      filtered = filtered.filter((g) =>
        g.normalized_name.includes(q) ||
        g.companies.some((c) => c.name.toLowerCase().includes(q) || String(c.id).includes(q))
      );
    }
    return filtered;
  }, [groups, dismissed, search]);

  const totalPages = Math.max(1, Math.ceil(activeGroups.length / PAGE_SIZE));
  const currentPage = Math.min(page, totalPages);
  const pagedGroups = activeGroups.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE);

  useEffect(() => { setPage(1); }, [search]);

  const handleMerge = async (keepId: number, removeId: number, groupName: string) => {
    if (!confirm(`Merge company #${removeId} into #${keepId}?\n\nAll audit requests, branches, and portal users will be moved.\nThe duplicate will be deleted.\n\nThis cannot be undone.`)) return;
    setMerging(groupName);
    try {
      const result = await fetchApi<MergeResult>(`${API_BASE}/companies/merge`, {
        method: "POST",
        body: JSON.stringify({ keep_id: keepId, remove_id: removeId }),
      });
      toast.success(`Merged "${result.removed_name}" → #${result.kept_id}. Moved: ${result.moved.audit_requests} requests, ${result.moved.branches} branches, ${result.moved.portal_users} users.`);
      fetchDuplicates();
      fetchHistory();
    } catch (err: any) {
      toast.error(err?.message || "Merge failed");
    } finally {
      setMerging(null);
    }
  };

  const handleDismiss = (groupName: string) => {
    setDismissed((prev) => new Set(prev).add(groupName));
    toast.success("Dismissed — not a duplicate");
  };

  return (
    <>
      <AppToaster />

      <div style={{
        background: "linear-gradient(135deg, #0c4a6e 0%, #1e40af 50%, #7c3aed 100%)",
        borderRadius: 14, padding: "24px 28px", marginBottom: 20, color: "#fff",
        display: "flex", justifyContent: "space-between", alignItems: "center",
      }}>
        <div>
          <h1 style={{ fontSize: 20, fontWeight: 600, margin: 0 }}>Merge duplicate companies</h1>
          <p style={{ fontSize: 13, margin: "4px 0 0", opacity: 0.7 }}>Review and merge companies with the same normalized name</p>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button onClick={() => setShowHistory(!showHistory)} style={{ padding: "7px 14px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.25)", background: showHistory ? "rgba(255,255,255,0.2)" : "rgba(255,255,255,0.1)", fontSize: 13, fontWeight: 500, cursor: "pointer", color: "#fff" }}>
            {showHistory ? "Hide history" : "Merge history"}
          </button>
          <button onClick={fetchDuplicates} disabled={loading} style={{ padding: "7px 14px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.25)", background: "rgba(255,255,255,0.1)", fontSize: 13, fontWeight: 500, cursor: loading ? "wait" : "pointer", color: "#fff" }}>
            {loading ? "Scanning..." : "Rescan"}
          </button>
        </div>
      </div>

      <div style={{ display: "flex", gap: 12, marginBottom: 16 }}>
        <StatCard value={activeGroups.length} label="Duplicate groups" color={activeGroups.length > 0 ? "warning" : "success"} />
        <StatCard value={activeGroups.reduce((s, g) => s + g.companies.length, 0)} label="Total duplicate records" color="neutral" />
        <StatCard value={history.length} label="Merges completed" color="neutral" />
      </div>

      <div style={{ display: "flex", gap: 12, alignItems: "center", marginBottom: 16, padding: "10px 16px", background: "#fff", border: "1px solid #e2e8f0", borderRadius: 10 }}>
        <span style={{ fontSize: 16, color: "#9ca3af" }}>🔍</span>
        <input type="text" placeholder="Search by company name, ID, or normalized name..." value={search} onChange={(e) => setSearch(e.target.value)} style={{ flex: 1, border: "none", outline: "none", fontSize: 14, background: "transparent", color: "#0f172a" }} />
        {search && <button onClick={() => setSearch("")} style={{ background: "none", border: "none", cursor: "pointer", fontSize: 14, color: "#9ca3af" }}>✕</button>}
        <span style={{ fontSize: 12, color: "#9ca3af", flexShrink: 0 }}>{activeGroups.length} result{activeGroups.length !== 1 ? "s" : ""}</span>
      </div>

      {showHistory && history.length > 0 && (
        <div style={{ marginBottom: 16, border: "1px solid #e2e8f0", borderRadius: 10, overflow: "hidden" }}>
          <div style={{ padding: "10px 16px", background: "#f8fafc", borderBottom: "1px solid #e2e8f0", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <span style={{ fontSize: 14, fontWeight: 500, color: "#0f172a" }}>Merge history</span>
            <span style={{ fontSize: 12, color: "#9ca3af" }}>{history.length} total</span>
          </div>
          <div style={{ maxHeight: 220, overflowY: "auto" }}>
            {history.map((h: any, idx: number) => (
              <div key={idx} style={{ padding: "8px 16px", borderBottom: idx < history.length - 1 ? "1px solid #f1f5f9" : "none", fontSize: 13, display: "flex", gap: 10, alignItems: "center" }}>
                <span style={{ color: "#9ca3af", fontSize: 11, flexShrink: 0, minWidth: 80 }}>{fmtDate(h.merged_at)}</span>
                <span style={{ color: "#dc2626", fontFamily: "monospace", fontSize: 12 }}>#{h.removed_id}</span>
                <span style={{ color: "#d1d5db" }}>→</span>
                <span style={{ color: "#059669", fontFamily: "monospace", fontSize: 12 }}>#{h.kept_id}</span>
                <span style={{ color: "#475569", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>&ldquo;{h.removed_name}&rdquo; → &ldquo;{h.kept_name || `#${h.kept_id}`}&rdquo;</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {loading && <div style={{ padding: 80, textAlign: "center", color: "#9ca3af", fontSize: 14 }}>Scanning for duplicates...</div>}

      {!loading && activeGroups.length === 0 && (
        <div style={{ padding: "80px 20px", textAlign: "center", border: "1px dashed #d1d5db", borderRadius: 12, color: "#6b7280" }}>
          <div style={{ fontSize: 40, marginBottom: 12 }}>✓</div>
          <div style={{ fontSize: 18, fontWeight: 500, marginBottom: 6, color: "#059669" }}>{search ? "No matches found" : "No duplicate companies"}</div>
          <div style={{ fontSize: 13 }}>{search ? `No groups match "${search}"` : "All company records have unique normalized names."}</div>
        </div>
      )}

      {pagedGroups.map((group) => {
        const sorted = [...group.companies].sort((a, b) => calcScore(b) - calcScore(a));
        const recommended = sorted[0];
        const isExpanded = expandedGroup === group.normalized_name;
        const isMerging = merging === group.normalized_name;
        return (
          <div key={group.normalized_name} style={{ border: "1px solid #e2e8f0", borderRadius: 12, overflow: "hidden", marginBottom: 10, opacity: isMerging ? 0.5 : 1, transition: "opacity 0.2s", boxShadow: isExpanded ? "0 2px 12px rgba(0,0,0,0.06)" : "none" }}>
            <div onClick={() => setExpandedGroup(isExpanded ? null : group.normalized_name)} style={{ padding: "12px 16px", background: isExpanded ? "#f0f9ff" : "#fafbfc", borderBottom: isExpanded ? "1px solid #e2e8f0" : "none", display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "pointer", transition: "background 0.15s" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <span style={{ width: 28, height: 28, borderRadius: 8, background: isExpanded ? "#dbeafe" : "#f1f5f9", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 600, color: isExpanded ? "#1e40af" : "#64748b" }}>{group.companies.length}</span>
                <div>
                  <span style={{ fontSize: 14, fontWeight: 500, color: "#0f172a" }}>&ldquo;{group.normalized_name}&rdquo;</span>
                  <span style={{ fontSize: 12, color: "#94a3b8", marginLeft: 8 }}>{group.companies.length} records</span>
                </div>
              </div>
              <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <span style={{ fontSize: 11, padding: "3px 10px", borderRadius: 10, background: "#fffbeb", color: "#b45309", fontWeight: 500 }}>Needs review</span>
                <span style={{ fontSize: 14, color: "#cbd5e1", transition: "transform 0.2s", transform: isExpanded ? "rotate(90deg)" : "none" }}>▶</span>
              </div>
            </div>
            {isExpanded && (
              <div style={{ padding: 16 }}>
                <div style={{ display: "flex", gap: 12, marginBottom: 14, flexWrap: "wrap" }}>
                  {sorted.map((c) => {
                    const isRec = c.id === recommended.id;
                    const score = calcScore(c);
                    return (
                      <div key={c.id} style={{ flex: "1 1 260px", border: isRec ? "2px solid #2563eb" : "1px solid #e2e8f0", borderRadius: 10, padding: 16, background: "#fff", position: "relative", transition: "border-color 0.15s" }}>
                        {isRec && <span style={{ position: "absolute", top: -9, left: 12, fontSize: 10, padding: "1px 8px", background: "#eff6ff", color: "#2563eb", borderRadius: 4, fontWeight: 600, border: "1px solid #bfdbfe" }}>Recommended keeper</span>}
                        <div style={{ fontSize: 14, fontWeight: 500, color: "#0f172a", marginBottom: 2 }}>{c.name}</div>
                        <div style={{ fontSize: 11, color: "#94a3b8", marginBottom: 12, fontFamily: "monospace" }}>ID: {c.id} · {c.company_code}</div>
                        <div style={{ fontSize: 12, color: "#475569", lineHeight: 1.9, marginBottom: 12 }}>
                          <div><strong>Contact:</strong> {c.contact_person && c.contact_person !== "Unknown" ? c.contact_person : <span style={{ color: "#d1d5db" }}>Unknown</span>}</div>
                          <div><strong>Email:</strong> {c.email && c.email !== "unknown@example.com" ? c.email : <span style={{ color: "#d1d5db" }}>None</span>}</div>
                          <div><strong>Group:</strong> {c.client_group || "—"}</div>
                          <div><strong>Created:</strong> {fmtDate(c.created_at)}</div>
                        </div>
                        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "4px 12px", fontSize: 11, color: "#64748b", padding: "10px 0", borderTop: "1px solid #f1f5f9" }}>
                          <div>📋 {c.audit_request_count} requests</div>
                          <div>📊 {c.audit_count} audits</div>
                          <div>🏢 {c.branch_count} branches</div>
                          <div>👤 {c.portal_user_count} portal users</div>
                          <div>📝 {c.inquiry_count} inquiries</div>
                          <div style={{ fontWeight: 600, color: isRec ? "#2563eb" : "#0f172a" }}>Score: {score}</div>
                        </div>
                        {!isRec && (
                          <div style={{ marginTop: 12, display: "flex", gap: 6 }}>
                            <button onClick={() => handleMerge(recommended.id, c.id, group.normalized_name)} disabled={isMerging} style={{ flex: 1, padding: "7px 12px", borderRadius: 8, border: "1px solid #bbf7d0", background: "#f0fdf4", fontSize: 12, fontWeight: 600, color: "#15803d", cursor: isMerging ? "not-allowed" : "pointer" }}>
                              Merge into #{recommended.id}
                            </button>
                            <button onClick={() => handleMerge(c.id, recommended.id, group.normalized_name)} disabled={isMerging} style={{ padding: "7px 12px", borderRadius: 8, border: "1px solid #e2e8f0", background: "#fff", fontSize: 12, color: "#64748b", cursor: isMerging ? "not-allowed" : "pointer" }}>
                              Keep this instead
                            </button>
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
                <div style={{ display: "flex", justifyContent: "flex-end" }}>
                  <button onClick={() => handleDismiss(group.normalized_name)} style={{ padding: "6px 14px", borderRadius: 8, border: "1px solid #e2e8f0", background: "#fff", fontSize: 12, color: "#9ca3af", cursor: "pointer" }}>Not a duplicate — dismiss</button>
                </div>
              </div>
            )}
          </div>
        );
      })}

      {!loading && activeGroups.length > PAGE_SIZE && (
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "14px 16px", marginTop: 12, background: "#fff", border: "1px solid #e2e8f0", borderRadius: 10 }}>
          <span style={{ fontSize: 13, color: "#64748b" }}>
            Showing {(currentPage - 1) * PAGE_SIZE + 1}–{Math.min(currentPage * PAGE_SIZE, activeGroups.length)} of {activeGroups.length} groups
          </span>
          <div style={{ display: "flex", gap: 4 }}>
            <PgBtn label="«" disabled={currentPage <= 1} onClick={() => setPage(1)} />
            <PgBtn label="‹" disabled={currentPage <= 1} onClick={() => setPage(currentPage - 1)} />
            {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
              let p: number;
              if (totalPages <= 5) p = i + 1;
              else if (currentPage <= 3) p = i + 1;
              else if (currentPage >= totalPages - 2) p = totalPages - 4 + i;
              else p = currentPage - 2 + i;
              return <PgBtn key={p} label={String(p)} active={p === currentPage} onClick={() => setPage(p)} />;
            })}
            <PgBtn label="›" disabled={currentPage >= totalPages} onClick={() => setPage(currentPage + 1)} />
            <PgBtn label="»" disabled={currentPage >= totalPages} onClick={() => setPage(totalPages)} />
          </div>
        </div>
      )}

      {!loading && activeGroups.length > 0 && (
        <div style={{ padding: "12px 16px", background: "#f8fafc", borderRadius: 10, border: "1px solid #e2e8f0", marginTop: 14, fontSize: 12, color: "#64748b", lineHeight: 1.7 }}>
          <strong>How merge works:</strong> All audit requests, branches, portal users, audits, and inquiries are moved from the duplicate to the keeper. Empty fields on the keeper are filled from the duplicate. The duplicate is deleted and logged in merge history. No data is lost.
        </div>
      )}
    </>
  );
}

function StatCard({ value, label, color }: { value: number; label: string; color: "warning" | "success" | "neutral" }) {
  const bg = color === "warning" ? "#fffbeb" : color === "success" ? "#f0fdf4" : "#f8fafc";
  const border = color === "warning" ? "#fde68a" : color === "success" ? "#bbf7d0" : "#e2e8f0";
  const numColor = color === "warning" ? "#b45309" : color === "success" ? "#15803d" : "#0f172a";
  const lblColor = color === "warning" ? "#d97706" : color === "success" ? "#059669" : "#64748b";
  return (
    <div style={{ flex: 1, padding: "14px 16px", borderRadius: 10, background: bg, border: `1px solid ${border}` }}>
      <div style={{ fontSize: 24, fontWeight: 600, color: numColor }}>{value}</div>
      <div style={{ fontSize: 12, color: lblColor, marginTop: 2 }}>{label}</div>
    </div>
  );
}

function PgBtn({ label, active, disabled, onClick }: { label: string; active?: boolean; disabled?: boolean; onClick: () => void }) {
  return (
    <button onClick={onClick} disabled={disabled} style={{
      width: 32, height: 32, borderRadius: 6, border: "1px solid #e2e8f0",
      background: active ? "#1e40af" : "#fff", color: active ? "#fff" : disabled ? "#d1d5db" : "#475569",
      fontSize: 13, fontWeight: 500, cursor: disabled ? "default" : "pointer",
      display: "flex", alignItems: "center", justifyContent: "center", opacity: disabled ? 0.5 : 1,
    }}>{label}</button>
  );
}