"use client";

import * as React from "react";
import { useSession } from "next-auth/react";
import { useQueryClient } from "@tanstack/react-query";
import {
  dealsApi,
  useGetQaVerificationStatsQuery,
  usePatchDiscoveryMeetingVerificationMutation,
  type Deal,
} from "@/api/rtk/deals-api";
import { useAppDispatch } from "@/store/hooks";
import { QaVerifyKpiStrip } from "@/components/qa-verify/qa-verify-kpi-strip";
import {
  QaVerifyLeadViewDialog,
} from "@/components/qa-verify/qa-verify-lead-view-dialog";
import { useGetProfileQuery } from "@/api/rtk/auth-api";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Spinner } from "@/components/ui/spinner";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { CheckCircle2, XCircle, Clock, RefreshCw, ShieldCheck, Search, Eye } from "lucide-react";
import { formatLeadMeetingMediumLabel } from "@/lib/lead-meeting-medium";
import { Input } from "@/components/ui/input";
import { ReactSelect } from "@/components/ui/react-select";
import { toast } from "sonner";
import { format } from "date-fns";
import { canVerifyClientMeetingVerification } from "@/lib/permissions";
import { useAuthToken } from "@/hooks/use-auth-token";
import { useUrlPagination } from "@/hooks/use-url-pagination";
import { leadsKeys } from "@/features/leads/api/query-keys";
import { useLeadsListPagedQuery } from "@/features/leads/hooks/use-leads-list-paged-query";
import type { LeadsListPageResult } from "@/features/leads/types";
import type { PermissionSource } from "@/lib/permissions";

const QA_PAGE_SIZE = 25;

const MULTILINE_CELL = "whitespace-normal align-top py-4";
/** Shrink-to-fit last column so actions sit beside status instead of far-right gap. */
const ACTIONS_HEAD = "w-[1%] whitespace-nowrap text-right";
const ACTIONS_CELL = "w-[1%] whitespace-nowrap align-top py-4";

type QaVerificationStatusFilter = "pending" | "verified" | "all";

const VERIFICATION_STATUS_OPTIONS: { value: QaVerificationStatusFilter; label: string }[] = [
  { value: "pending", label: "Pending verification" },
  { value: "verified", label: "Verified" },
  { value: "all", label: "All leads" },
];

function MeetingCell({
  meetingDate,
  medium,
  notes,
}: {
  meetingDate?: string | null;
  medium?: string | null;
  notes?: string | null;
}) {
  const formattedDate = meetingDate
    ? (() => {
        const dt = new Date(meetingDate);
        return isNaN(dt.getTime()) ? null : format(dt, "MMM d, yyyy h:mm a");
      })()
    : null;
  const mediumLabel = formatLeadMeetingMediumLabel(medium, notes);
  const hasMedium = mediumLabel !== "—";

  if (!formattedDate && !hasMedium) {
    return <span className="text-sm text-gray-300">—</span>;
  }

  return (
    <div className="space-y-1 text-sm leading-relaxed">
      {formattedDate ? (
        <div className="font-medium text-gray-800">{formattedDate}</div>
      ) : null}
      {hasMedium ? <div className="text-gray-500">{mediumLabel}</div> : null}
    </div>
  );
}

function VerificationStatusBadge({
  showup,
  verifiedAt,
  verifiedBy,
}: {
  showup?: boolean | null;
  verifiedAt?: string | null;
  verifiedBy?: string | null;
}) {
  if (showup === true) {
    return (
      <div className="inline-flex flex-col items-start gap-1">
        <Badge className="whitespace-nowrap bg-emerald-100 text-emerald-800 hover:bg-emerald-100">
          <CheckCircle2 className="mr-1 size-3.5 shrink-0" />
          Showed up
        </Badge>
        {verifiedAt ? (
          <span className="text-xs text-gray-400">
            {format(new Date(verifiedAt), "MMM d, h:mm a")}
            {verifiedBy ? ` · ${verifiedBy}` : ""}
          </span>
        ) : null}
      </div>
    );
  }

  if (showup === false) {
    return (
      <div className="inline-flex flex-col items-start gap-1">
        <Badge className="whitespace-nowrap bg-red-100 text-red-800 hover:bg-red-100">
          <XCircle className="mr-1 size-3.5 shrink-0" />
          No show
        </Badge>
        {verifiedAt ? (
          <span className="text-xs text-gray-400">
            {format(new Date(verifiedAt), "MMM d, h:mm a")}
            {verifiedBy ? ` · ${verifiedBy}` : ""}
          </span>
        ) : null}
      </div>
    );
  }

  return (
    <Badge
      variant="secondary"
      className="whitespace-nowrap bg-amber-50 text-amber-800 hover:bg-amber-50"
      title="Awaiting QA verification"
    >
      <Clock className="mr-1 size-3.5 shrink-0" />
      Pending QA
    </Badge>
  );
}

export default function QaVerifyLeadsPage() {
  const queryClient = useQueryClient();
  const dispatch = useAppDispatch();
  const [viewLead, setViewLead] = React.useState<Deal | null>(null);
  const { data: nextAuthSession } = useSession();
  const { token } = useAuthToken();
  const backendUser = (nextAuthSession as { backendUser?: PermissionSource } | null)?.backendUser ?? null;
  const { data: profile } = useGetProfileQuery(undefined, { skip: !token });

  const permissionSource: PermissionSource = backendUser ?? profile ?? null;

  const canVerify = canVerifyClientMeetingVerification(permissionSource);

  // Search filter (server-side via deals API)
  const [searchInput, setSearchInput] = React.useState("");
  const [debouncedSearch, setDebouncedSearch] = React.useState("");
  const [verificationStatus, setVerificationStatus] =
    React.useState<QaVerificationStatusFilter>("pending");

  const { page, setPage, limit: pageSize } = useUrlPagination(QA_PAGE_SIZE);

  React.useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(searchInput.trim());
    }, 300);
    return () => clearTimeout(timer);
  }, [searchInput]);

  React.useEffect(() => {
    setPage(1);
  }, [debouncedSearch, verificationStatus, setPage]);

  const listParams = React.useMemo(
    () => ({
      qaVerificationStatus: verificationStatus,
      stageType: "Lead" as const,
      ...(debouncedSearch ? { search: debouncedSearch } : {}),
      page,
      limit: pageSize,
    }),
    [debouncedSearch, verificationStatus, page, pageSize],
  );

  const statsQueryArgs = React.useMemo(
    () => (debouncedSearch ? { search: debouncedSearch } : undefined),
    [debouncedSearch],
  );

  const {
    data: stats,
    isLoading: statsLoading,
    isFetching: statsFetching,
  } = useGetQaVerificationStatsQuery(statsQueryArgs, { skip: !canVerify });

  // Only fetch the list if the user actually has QA verify permission
  const {
    data: pageResult,
    isLoading,
    isFetching,
    refetch,
  } = useLeadsListPagedQuery(listParams, {
    enabled: canVerify,
    staleTime: 60_000,
    gcTime: 5 * 60_000,
  });

  const listQueryKey = React.useMemo(
    () => leadsKeys.listPage({ ...listParams, limit: pageSize, page }),
    [listParams, pageSize, page],
  );

  const leads = pageResult?.items ?? [];
  const total = pageResult?.total ?? 0;
  const totalPages = total > 0 ? Math.ceil(total / pageSize) : 0;

  const [patchVerification, { isLoading: verifying }] =
    usePatchDiscoveryMeetingVerificationMutation();

  const handleVerify = async (lead: Deal, clientShowup: boolean) => {
    const previousList = queryClient.getQueryData<LeadsListPageResult>(listQueryKey);
    const verifiedAt = new Date().toISOString();

    queryClient.setQueryData<LeadsListPageResult>(listQueryKey, (current) => {
      if (!current) return current;
      if (verificationStatus === "pending") {
        const items = current.items.filter((item) => item.id !== lead.id);
        return {
          ...current,
          items,
          total:
            current.total != null ? Math.max(0, current.total - 1) : current.total,
        };
      }
      return {
        ...current,
        items: current.items.map((item) =>
          item.id === lead.id
            ? {
                ...item,
                discoveryMeetingClientShowup: clientShowup,
                discoveryMeetingVerifiedAt: verifiedAt,
              }
            : item,
        ),
      };
    });

    const statsPatch = dispatch(
      dealsApi.util.updateQueryData(
        "getQaVerificationStats",
        statsQueryArgs,
        (draft) => {
          draft.pendingCount = Math.max(0, draft.pendingCount - 1);
          draft.verifiedTodayCount += 1;
          if (clientShowup) {
            draft.verifiedTodayShowupCount += 1;
          } else {
            draft.verifiedTodayNoShowCount += 1;
          }
          draft.verifiedByYouTodayCount += 1;
          const verified = draft.verifiedTodayCount;
          draft.showUpRateTodayPct =
            verified > 0
              ? Math.round((draft.verifiedTodayShowupCount / verified) * 1000) / 10
              : null;
        },
      ),
    );

    try {
      await patchVerification({ id: lead.id, clientShowup }).unwrap();
      toast.success(
        clientShowup ? "Marked as client showed up" : "Marked as no-show",
      );
      void refetch().then(({ data: refreshed }) => {
        if ((refreshed?.items.length ?? 0) === 0 && page > 1) {
          setPage(page - 1);
        }
      });
    } catch {
      if (previousList) {
        queryClient.setQueryData(listQueryKey, previousList);
      }
      statsPatch.undo();
      toast.error("Could not save verification");
    }
  };

  const formatDate = (d?: string | null) => {
    if (!d) return "—";
    const dt = new Date(d);
    return isNaN(dt.getTime()) ? "—" : format(dt, "MMM d, yyyy");
  };

  // Gate the entire page content behind the QA verify permission
  if (!canVerify) {
    return (
      <div className="p-6">
        <div className="mx-auto max-w-md rounded-2xl border bg-white p-8 text-center shadow-sm">
          <div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-red-100">
            <ShieldCheck className="size-7 text-red-600" />
          </div>
          <h1 className="text-xl font-semibold">Access restricted</h1>
          <p className="mt-2 text-sm text-muted-foreground">
            This page is only available to users with the QA verify permission
            (CLIENT_MEETING_VERIFICATION).
          </p>
          <p className="mt-1 text-xs text-muted-foreground">
            Contact an administrator if you need access to verify discovery meeting attendance.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="p-6 space-y-6">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
        <div className="flex flex-col gap-1">
          <h1 className="text-2xl font-extrabold tracking-tight text-[#101828] font-['Lexend'] sm:text-3xl">
            QA Verify Leads
          </h1>
          <p className="text-sm text-[#475467]">
            Record discovery meeting attendance for leads awaiting QA verification.
          </p>
        </div>
        <div className="flex flex-wrap items-center justify-end gap-2">
          <ReactSelect
            value={verificationStatus}
            onValueChange={(value) =>
              setVerificationStatus(value as QaVerificationStatusFilter)
            }
            options={VERIFICATION_STATUS_OPTIONS}
            placeholder="Verification status"
            triggerClassName="h-8 w-full min-w-[168px] text-xs sm:w-[180px]"
          />
          <div className="relative w-full sm:w-64">
            <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              placeholder="Search name, phone, email, owner..."
              className="h-8 pl-9 text-sm"
            />
          </div>
          <Button
            variant="outline"
            size="sm"
            className="h-7 px-2.5 text-xs"
            onClick={() => refetch()}
            disabled={isFetching}
          >
            <RefreshCw className={`mr-1.5 size-3 ${isFetching ? "animate-spin" : ""}`} />
            Refresh
          </Button>
        </div>
      </div>

      <QaVerifyKpiStrip
        stats={stats}
        filteredTotal={total}
        isLoading={statsLoading}
        isUpdating={statsFetching && !statsLoading}
        hasSearch={Boolean(debouncedSearch)}
      />

      {isLoading ? (
        <div className="flex h-40 items-center justify-center">
          <Spinner />
        </div>
      ) : leads.length === 0 ? (
        <div className="rounded-2xl border bg-white p-10 text-center">
          <div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-emerald-100">
            <CheckCircle2 className="size-6 text-emerald-600" />
          </div>
          <div className="text-lg font-medium">
            {debouncedSearch
              ? "No matches found"
              : verificationStatus === "pending"
                ? "All caught up"
                : verificationStatus === "verified"
                  ? "No verified leads"
                  : "No leads found"}
          </div>
          <p className="mt-1 text-sm text-muted-foreground">
            {debouncedSearch
              ? `No leads match “${debouncedSearch}”.`
              : verificationStatus === "pending"
                ? "No leads currently awaiting QA verification."
                : verificationStatus === "verified"
                  ? "No leads have been verified yet."
                  : "No leads match the current filters."}
          </p>
        </div>
      ) : (
        <div className="space-y-3">
        <Table className="min-w-[1100px]">
          <TableHeader className="sticky top-0 z-10">
            <TableRow className="cursor-default hover:bg-transparent">
              <TableHead className="min-w-[180px]">Lead</TableHead>
              <TableHead className="min-w-[160px]">Contact</TableHead>
              <TableHead className="min-w-[150px]">Owner / Team</TableHead>
              <TableHead className="min-w-[180px]">Meeting</TableHead>
              <TableHead className="min-w-[110px]">First transaction</TableHead>
              <TableHead className="min-w-[110px]">Created</TableHead>
              <TableHead className="min-w-[110px]">Updated</TableHead>
              <TableHead className="min-w-[150px]">Status</TableHead>
              <TableHead className={ACTIONS_HEAD}>Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {leads.map((lead) => {
              const showup = lead.discoveryMeetingClientShowup;
              const verifiedAt = lead.discoveryMeetingVerifiedAt;
              const verifiedBy = lead.discoveryMeetingVerifiedBy?.name;
              const isVerified = showup != null;

              return (
                <TableRow key={lead.id} className="cursor-default">
                  <TableCell className={MULTILINE_CELL}>
                    <div className="min-w-[160px] max-w-[220px]">
                      <div
                        className="font-medium text-gray-900"
                        title={lead.customerName ?? undefined}
                      >
                        {lead.customerName || "—"}
                      </div>
                      {lead.leadId ? (
                        <div className="mt-0.5 break-all text-xs text-gray-500">{lead.leadId}</div>
                      ) : null}
                    </div>
                  </TableCell>
                  <TableCell className={MULTILINE_CELL}>
                    <div className="min-w-[140px] space-y-1 text-sm leading-relaxed">
                      <div className="text-gray-800">{lead.phone || "—"}</div>
                      {lead.email ? (
                        <div className="break-all text-gray-500" title={lead.email}>
                          {lead.email}
                        </div>
                      ) : null}
                    </div>
                  </TableCell>
                  <TableCell className={MULTILINE_CELL}>
                    <div className="min-w-[130px] space-y-1 text-sm leading-relaxed">
                      <div className="text-gray-800" title={lead.owner?.name ?? undefined}>
                        {lead.owner?.name || "—"}
                      </div>
                      {lead.team ? (
                        <div className="text-gray-500" title={lead.team}>
                          {lead.team}
                        </div>
                      ) : null}
                    </div>
                  </TableCell>
                  <TableCell className={MULTILINE_CELL}>
                    <MeetingCell
                      meetingDate={lead.latestLeadMeeting?.meetingDate}
                      medium={lead.latestLeadMeeting?.medium}
                      notes={lead.latestLeadMeeting?.notes}
                    />
                  </TableCell>
                  <TableCell className="text-sm text-gray-600">
                    {formatDate(lead.firstPaidOn)}
                  </TableCell>
                  <TableCell className="text-sm text-gray-600">
                    {formatDate(lead.createdDate || lead.createdAt)}
                  </TableCell>
                  <TableCell className="text-sm text-gray-600">
                    {formatDate(lead.updatedAt)}
                  </TableCell>
                  <TableCell className={MULTILINE_CELL}>
                    <VerificationStatusBadge
                      showup={showup}
                      verifiedAt={verifiedAt}
                      verifiedBy={verifiedBy}
                    />
                  </TableCell>
                  <TableCell className={ACTIONS_CELL}>
                    <div className="flex items-center gap-1.5">
                      <Button
                        size="sm"
                        variant="ghost"
                        className="h-8 shrink-0 px-2.5 text-xs"
                        onClick={() => setViewLead(lead)}
                        aria-label={`View lead ${lead.customerName ?? lead.leadId ?? lead.id}`}
                      >
                        <Eye className="mr-1 size-3.5" />
                        View Lead
                      </Button>
                      {!isVerified ? (
                        <>
                          <Button
                            size="sm"
                            variant="outline"
                            className="h-8 shrink-0 border-emerald-200 px-2.5 text-xs text-emerald-700 hover:bg-emerald-50"
                            disabled={verifying}
                            onClick={() => handleVerify(lead, true)}
                          >
                            <CheckCircle2 className="mr-1 size-3.5" />
                            Showed up
                          </Button>
                          <Button
                            size="sm"
                            variant="outline"
                            className="h-8 shrink-0 border-red-200 px-2.5 text-xs text-red-700 hover:bg-red-50"
                            disabled={verifying}
                            onClick={() => handleVerify(lead, false)}
                          >
                            <XCircle className="mr-1 size-3.5" />
                            No show
                          </Button>
                        </>
                      ) : null}
                    </div>
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>

        {total > 0 && (
          <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
            <span className="text-xs text-muted-foreground">
              Showing {(page - 1) * pageSize + 1}–{Math.min(page * pageSize, total)} of {total}
            </span>
            {totalPages > 1 && (
              <Pagination className="mx-0 w-auto justify-end">
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious
                      href="#"
                      onClick={(e) => {
                        e.preventDefault();
                        if (page > 1) setPage(page - 1);
                      }}
                      className={page <= 1 ? "pointer-events-none opacity-50" : "cursor-pointer"}
                    />
                  </PaginationItem>
                  <PaginationItem>
                    <span className="px-3 text-xs font-medium text-muted-foreground">
                      {page} / {totalPages}
                    </span>
                  </PaginationItem>
                  <PaginationItem>
                    <PaginationNext
                      href="#"
                      onClick={(e) => {
                        e.preventDefault();
                        if (page < totalPages) setPage(page + 1);
                      }}
                      className={
                        page >= totalPages ? "pointer-events-none opacity-50" : "cursor-pointer"
                      }
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>
            )}
          </div>
        )}
        </div>
      )}

      <QaVerifyLeadViewDialog
        lead={viewLead}
        open={viewLead != null}
        onOpenChange={(open) => {
          if (!open) setViewLead(null);
        }}
      />
    </div>
  );
}
