"use client";

import type { ColumnDef } from "@tanstack/react-table";
import {
  MoreHorizontal,
  Eye,
  CheckCircle,
  Trash2,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  RefreshCw,
  Check,
  X,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import { ImagePreview } from "./image-preview";

function SortableHeader({
  column,
  children,
}: {
  column: {
    getIsSorted: () => false | "asc" | "desc";
    getToggleSortingHandler: () => ((event: unknown) => void) | undefined;
  };
  children: React.ReactNode;
}) {
  const sorted = column.getIsSorted();
  return (
    <Button
      variant="ghost"
      size="sm"
      className="-ml-2 h-8 font-medium hover:bg-transparent"
      onClick={column.getToggleSortingHandler()}
    >
      {children}
      {sorted === "asc" ? (
        <ArrowUp className="ml-1 size-4" />
      ) : sorted === "desc" ? (
        <ArrowDown className="ml-1 size-4" />
      ) : (
        <ArrowUpDown className="ml-1 size-4 opacity-50" />
      )}
    </Button>
  );
}

function BoolCell({ value }: { value: boolean }) {
  return value ? (
    <Check className="size-4 text-green-600 dark:text-green-400" />
  ) : (
    <X className="size-4 text-muted-foreground/40" />
  );
}

function JsonCell({ value }: { value: unknown }) {
  if (!value) return <span className="text-muted-foreground">—</span>;
  const arr = Array.isArray(value) ? value : [value];
  const text = arr.filter(Boolean).join(", ");
  return (
    <span className="text-muted-foreground max-w-[200px] truncate block" title={text}>
      {text || "—"}
    </span>
  );
}

export type ResponseCard = {
  id: string;
  createdAt: string;
  name: string | null;
  email: string | null;
  cellPhone: string | null;
  homePhone: string | null;
  address: string | null;
  aptNumber: string | null;
  city: string | null;
  state: string | null;
  zip: string | null;
  gender: string | null;
  dateOfBirth: string | null;
  maritalStatus: string | null;
  maritalStatusOther: string | null;
  visitType: string | null;
  prayerRequests: string | null;
  prayerForTeam: boolean;
  prayerConfidential: boolean;
  messageTopics: unknown;
  messageTopicsOther: string | null;
  nextStep: unknown;
  attendanceDuration: string | null;
  campusPreference: unknown;
  campusPreferenceOther: string | null;
  howHeard: unknown;
  howHeardOther: string | null;
  serviceAttended: string | null;
  followUp: string | null;
  notes: string | null;
  serviceTime: string | null;
  planningCenter: string | null;
  iSaidYesBookSent: boolean;
  ftGuestLetterSent: boolean;
  firstTimeGuestDate: string | null;
  salvationDate: string | null;
  mondayItemId: string | null;
  assignedToId: string | null;
  assignedById: string | null;
  assignedAt: string | null;
  reviewedById: string | null;
  reviewedAt: string | null;
  reviewNotes: string | null;
  ocrStatus: string;
  reviewStatus: string;
  ocrConfidence: number | null;
  frontImageUrl: string | null;
  backImageUrl: string | null;
  assignedToName?: string | null;
  reviewedByName?: string | null;
};

export const COPYABLE_FIELDS: { field: keyof ResponseCard; label: string }[] = [
  { field: "name", label: "Name" },
  { field: "email", label: "Email" },
  { field: "cellPhone", label: "Phone" },
  { field: "homePhone", label: "Home Phone" },
  { field: "address", label: "Address" },
  { field: "city", label: "City" },
  { field: "state", label: "State" },
  { field: "zip", label: "Zip" },
  { field: "gender", label: "Gender" },
  { field: "dateOfBirth", label: "Date of Birth" },
  { field: "maritalStatus", label: "Marital Status" },
  { field: "visitType", label: "Visit Type" },
  { field: "attendanceDuration", label: "Attendance" },
  { field: "serviceAttended", label: "Service" },
  { field: "prayerRequests", label: "Prayer Requests" },
  { field: "followUp", label: "Follow-Up" },
  { field: "notes", label: "Notes" },
  { field: "reviewStatus", label: "Review Status" },
  { field: "ocrStatus", label: "OCR Status" },
];

const ocrStatusVariant: Record<string, string> = {
  pending: "bg-muted text-muted-foreground",
  processing: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300",
  complete: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300",
  error: "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300",
};

const reviewStatusVariant: Record<string, string> = {
  unreviewed:
    "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300",
  assigned:
    "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300",
  in_review:
    "bg-cyan-100 text-cyan-800 dark:bg-cyan-900/30 dark:text-cyan-300",
  reviewed: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300",
  exported: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300",
};

function getOcrBadgeClass(status: string): string {
  return ocrStatusVariant[status.toLowerCase()] ?? ocrStatusVariant.pending;
}

function getReviewBadgeClass(status: string): string {
  return (
    reviewStatusVariant[status.toLowerCase()] ?? reviewStatusVariant.unreviewed
  );
}

function getConfidenceClass(confidence: number | null): string {
  if (confidence == null) return "text-muted-foreground";
  if (confidence < 50) return "text-red-600 dark:text-red-400 font-medium";
  if (confidence <= 75) return "text-amber-600 dark:text-amber-400 font-medium";
  return "text-green-600 dark:text-green-400 font-medium";
}

export type ColumnActions = {
  onViewDetails?: (card: ResponseCard) => void;
  onMarkReviewed?: (card: ResponseCard) => void;
  onReprocess?: (card: ResponseCard) => void;
  onDelete?: (card: ResponseCard) => void;
};

export function createColumns(actions?: ColumnActions): ColumnDef<ResponseCard>[] {
  return [
    {
      id: "select",
      header: ({ table }) => (
        <Checkbox
          checked={table.getIsAllPageRowsSelected()}
          indeterminate={
            table.getIsSomePageRowsSelected() &&
            !table.getIsAllPageRowsSelected()
          }
          onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
          aria-label="Select all"
        />
      ),
      cell: ({ row }) => (
        <Checkbox
          checked={row.getIsSelected()}
          onCheckedChange={(value) => row.toggleSelected(!!value)}
          aria-label="Select row"
        />
      ),
      enableSorting: false,
      enableHiding: false,
      meta: { noCopy: true },
    },
    {
      accessorKey: "frontImageUrl",
      id: "thumbnail",
      header: "",
      cell: ({ row }) => (
        <ImagePreview
          imageUrl={row.original.frontImageUrl ?? row.original.backImageUrl}
          alt={row.original.name ?? "Card"}
        />
      ),
      enableSorting: false,
      enableHiding: true,
      meta: { noCopy: true },
    },
    {
      accessorKey: "name",
      header: ({ column }) => (
        <SortableHeader column={column}>Name</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="font-medium">
          {row.getValue("name") ?? "—"}
        </span>
      ),
      meta: { sticky: true },
    },
    {
      accessorKey: "email",
      header: ({ column }) => (
        <SortableHeader column={column}>Email</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("email") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "cellPhone",
      header: ({ column }) => (
        <SortableHeader column={column}>Phone</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("cellPhone") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "homePhone",
      header: "Home Phone",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("homePhone") ?? "—"}
        </span>
      ),
    },
    {
      id: "location",
      header: "Location",
      cell: ({ row }) => {
        const city = row.original.city;
        const state = row.original.state;
        const loc = [city, state].filter(Boolean).join(", ");
        return (
          <span className="text-muted-foreground">{loc || "—"}</span>
        );
      },
      enableSorting: false,
    },
    {
      accessorKey: "address",
      header: "Address",
      cell: ({ row }) => (
        <span className="text-muted-foreground max-w-[180px] truncate block" title={row.getValue("address") ?? ""}>
          {row.getValue("address") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "zip",
      header: "Zip",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("zip") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "gender",
      header: ({ column }) => (
        <SortableHeader column={column}>Gender</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("gender") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "dateOfBirth",
      header: "DOB",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("dateOfBirth") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "maritalStatus",
      header: "Marital Status",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("maritalStatus") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "visitType",
      header: ({ column }) => (
        <SortableHeader column={column}>Visit Type</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("visitType") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "attendanceDuration",
      header: ({ column }) => (
        <SortableHeader column={column}>Attendance</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("attendanceDuration") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "serviceAttended",
      header: ({ column }) => (
        <SortableHeader column={column}>Service</SortableHeader>
      ),
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("serviceAttended") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "prayerRequests",
      header: "Prayer Requests",
      cell: ({ row }) => (
        <span className="text-muted-foreground max-w-[200px] truncate block" title={row.getValue("prayerRequests") ?? ""}>
          {row.getValue("prayerRequests") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "prayerForTeam",
      header: "Prayer Team",
      cell: ({ row }) => <BoolCell value={row.original.prayerForTeam} />,
    },
    {
      accessorKey: "prayerConfidential",
      header: "Confidential",
      cell: ({ row }) => <BoolCell value={row.original.prayerConfidential} />,
    },
    {
      accessorKey: "messageTopics",
      id: "messageTopics",
      header: "Message Topics",
      cell: ({ row }) => <JsonCell value={row.original.messageTopics} />,
      enableSorting: false,
    },
    {
      accessorKey: "nextStep",
      id: "nextStep",
      header: "Next Step",
      cell: ({ row }) => <JsonCell value={row.original.nextStep} />,
      enableSorting: false,
    },
    {
      accessorKey: "campusPreference",
      id: "campusPreference",
      header: "Campus",
      cell: ({ row }) => <JsonCell value={row.original.campusPreference} />,
      enableSorting: false,
    },
    {
      accessorKey: "howHeard",
      id: "howHeard",
      header: "How Heard",
      cell: ({ row }) => <JsonCell value={row.original.howHeard} />,
      enableSorting: false,
    },
    {
      accessorKey: "followUp",
      header: "Follow-Up",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("followUp") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "notes",
      header: "Notes",
      cell: ({ row }) => (
        <span className="text-muted-foreground max-w-[200px] truncate block" title={row.getValue("notes") ?? ""}>
          {row.getValue("notes") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "serviceTime",
      header: "Service Time",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("serviceTime") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "planningCenter",
      header: "Planning Center",
      cell: ({ row }) => (
        <span className="text-muted-foreground">
          {row.getValue("planningCenter") ?? "—"}
        </span>
      ),
    },
    {
      accessorKey: "iSaidYesBookSent",
      header: "I Said Yes Book",
      cell: ({ row }) => <BoolCell value={row.original.iSaidYesBookSent} />,
    },
    {
      accessorKey: "ftGuestLetterSent",
      header: "FT Guest Letter",
      cell: ({ row }) => <BoolCell value={row.original.ftGuestLetterSent} />,
    },
    {
      accessorKey: "firstTimeGuestDate",
      header: "FT Guest Date",
      cell: ({ row }) => {
        const v = row.original.firstTimeGuestDate;
        return <span className="truncate text-sm">{v ? new Date(v).toLocaleDateString() : "—"}</span>;
      },
    },
    {
      accessorKey: "salvationDate",
      header: "Salvation Date",
      cell: ({ row }) => {
        const v = row.original.salvationDate;
        return <span className="truncate text-sm">{v ? new Date(v).toLocaleDateString() : "—"}</span>;
      },
    },
    {
      id: "mondayLinked",
      header: "Monday.com",
      cell: ({ row }) =>
        row.original.mondayItemId ? (
          <Badge variant="secondary" className="bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 text-[10px]">
            Linked
          </Badge>
        ) : (
          <span className="text-muted-foreground">—</span>
        ),
      enableSorting: false,
    },
    {
      id: "assignedTo",
      header: "Assigned To",
      cell: ({ row }) => (
        <span className="text-muted-foreground text-sm">
          {row.original.assignedToName ?? "—"}
        </span>
      ),
      enableSorting: false,
    },
    {
      id: "reviewedBy",
      header: "Reviewed By",
      cell: ({ row }) => (
        <span className="text-muted-foreground text-sm">
          {row.original.reviewedByName ?? "—"}
        </span>
      ),
      enableSorting: false,
    },
    {
      accessorKey: "ocrStatus",
      header: ({ column }) => (
        <SortableHeader column={column}>OCR Status</SortableHeader>
      ),
      cell: ({ row }) => {
        const status = String(row.getValue("ocrStatus") ?? "pending");
        return (
          <Badge
            variant="secondary"
            className={cn("capitalize", getOcrBadgeClass(status))}
          >
            {status}
          </Badge>
        );
      },
    },
    {
      accessorKey: "reviewStatus",
      header: ({ column }) => (
        <SortableHeader column={column}>Review</SortableHeader>
      ),
      cell: ({ row }) => {
        const status = String(row.getValue("reviewStatus") ?? "unreviewed");
        return (
          <Badge
            variant="secondary"
            className={cn("capitalize", getReviewBadgeClass(status))}
          >
            {status}
          </Badge>
        );
      },
    },
    {
      accessorKey: "ocrConfidence",
      header: ({ column }) => (
        <SortableHeader column={column}>Confidence</SortableHeader>
      ),
      cell: ({ row }) => {
        const val = row.getValue("ocrConfidence") as number | null;
        const pct = val != null ? Math.round(val) : null;
        return (
          <span className={cn(getConfidenceClass(val ?? 0))}>
            {pct != null ? `${pct}%` : "—"}
          </span>
        );
      },
    },
    {
      id: "actions",
      header: "",
      cell: ({ row }) => (
        <DropdownMenu>
          <DropdownMenuTrigger
            render={
              <Button
                variant="ghost"
                size="icon-sm"
                className="size-7"
                aria-label="Open menu"
              />
            }
          >
            <MoreHorizontal className="size-4" />
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            {actions?.onViewDetails && (
              <DropdownMenuItem
                onClick={() => actions.onViewDetails?.(row.original)}
              >
                <Eye className="mr-2 size-4" />
                View details
              </DropdownMenuItem>
            )}
            {actions?.onMarkReviewed && (
              <DropdownMenuItem
                onClick={() => actions.onMarkReviewed?.(row.original)}
              >
                <CheckCircle className="mr-2 size-4" />
                Mark reviewed
              </DropdownMenuItem>
            )}
            {actions?.onReprocess &&
              row.original.ocrStatus !== "processing" && (
                <DropdownMenuItem
                  onClick={() => actions.onReprocess?.(row.original)}
                >
                  <RefreshCw className="mr-2 size-4" />
                  Reprocess
                </DropdownMenuItem>
              )}
            {actions?.onDelete && (
              <DropdownMenuItem
                variant="destructive"
                onClick={() => actions.onDelete?.(row.original)}
              >
                <Trash2 className="mr-2 size-4" />
                Delete
              </DropdownMenuItem>
            )}
          </DropdownMenuContent>
        </DropdownMenu>
      ),
      enableSorting: false,
      enableHiding: false,
      meta: { noCopy: true },
    },
  ];
}

export const columns = createColumns();
