"use client";

import * as React from "react";
import { useRouter, usePathname, useSearchParams } from "next/navigation";
import { Search, Download, Upload, Columns3 } from "lucide-react";
import type { VisibilityState } from "@tanstack/react-table";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Checkbox } from "@/components/ui/checkbox";
import { ALL_TOGGLEABLE_COLUMNS } from "./data-table";

const COLUMN_GROUPS: { label: string; ids: string[] }[] = [
  { label: "Core", ids: ["thumbnail", "name", "email", "cellPhone", "location", "visitType", "ocrStatus", "reviewStatus", "ocrConfidence"] },
  { label: "Personal", ids: ["homePhone", "gender", "dateOfBirth", "maritalStatus", "address", "zip"] },
  { label: "Survey", ids: ["attendanceDuration", "serviceAttended", "messageTopics", "nextStep", "campusPreference", "howHeard"] },
  { label: "Prayer", ids: ["prayerRequests", "prayerForTeam", "prayerConfidential"] },
  { label: "Workflow", ids: ["followUp", "notes", "serviceTime", "planningCenter", "iSaidYesBookSent", "ftGuestLetterSent", "mondayLinked", "assignedTo", "reviewedBy"] },
];

const COL_LABELS: Record<string, string> = {};
for (const col of ALL_TOGGLEABLE_COLUMNS) {
  COL_LABELS[col.id] = col.label;
}

type UserOption = { id: string; displayName: string };

export type FiltersProps = {
  search?: string;
  visitType?: string;
  attendanceDuration?: string;
  serviceAttended?: string;
  visitTypeOptions?: string[];
  attendanceDurationOptions?: string[];
  serviceAttendedOptions?: string[];
  onExportCsv?: () => void;
  onUploadClick?: () => void;
  columnVisibility?: VisibilityState;
  onColumnVisibilityChange?: (visibility: VisibilityState) => void;
  showAssignedToFilter?: boolean;
};

export function Filters({
  search: initialSearch = "",
  visitType: initialVisitType = "",
  attendanceDuration: initialAttendanceDuration = "",
  serviceAttended: initialServiceAttended = "",
  visitTypeOptions = [],
  attendanceDurationOptions = [],
  serviceAttendedOptions = [],
  onExportCsv,
  onUploadClick,
  columnVisibility = {},
  onColumnVisibilityChange,
  showAssignedToFilter = false,
}: FiltersProps) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [users, setUsers] = React.useState<UserOption[]>([]);

  React.useEffect(() => {
    if (!showAssignedToFilter) return;
    fetch("/api/users")
      .then((r) => r.json())
      .then((data) => setUsers(data.users || []))
      .catch(() => {});
  }, [showAssignedToFilter]);

  const search = searchParams.get("search") ?? initialSearch;
  const visitType = searchParams.get("visitType") ?? initialVisitType;
  const attendanceDuration =
    searchParams.get("attendanceDuration") ?? initialAttendanceDuration;
  const serviceAttended =
    searchParams.get("serviceAttended") ?? initialServiceAttended;
  const assignedToId = searchParams.get("assignedToId") ?? "";

  const updateParams = React.useCallback(
    (updates: Record<string, string | undefined>) => {
      const params = new URLSearchParams(searchParams.toString());
      for (const [key, value] of Object.entries(updates)) {
        if (value === undefined || value === "") {
          params.delete(key);
        } else {
          params.set(key, value);
        }
      }
      params.set("page", "1");
      router.push(`${pathname}?${params.toString()}`);
    },
    [pathname, router, searchParams]
  );

  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const v = e.target.value;
    updateParams({ search: v || undefined });
  };

  const isVisible = (id: string) => columnVisibility[id] !== false;
  const toggleCol = (id: string, checked: boolean) => {
    onColumnVisibilityChange?.({ ...columnVisibility, [id]: checked });
  };

  const visibleCount = ALL_TOGGLEABLE_COLUMNS.filter((c) => isVisible(c.id)).length;

  return (
    <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
      <div className="flex flex-1 flex-col gap-2 sm:flex-row sm:items-center">
        <div className="relative w-full sm:max-w-xs">
          <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            type="search"
            placeholder="Search..."
            value={search}
            onChange={handleSearchChange}
            className="pl-9 rounded-xl"
          />
        </div>

        <div className="flex flex-wrap items-center gap-2">
          <Select
            value={visitType || null}
            onValueChange={(v: string | null) =>
              updateParams({ visitType: !v || v === "__all__" ? undefined : v })
            }
          >
            <SelectTrigger className="w-[140px] rounded-xl">
              <SelectValue placeholder="Visit Type" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__all__">All visits</SelectItem>
              {visitTypeOptions.map((opt) => (
                <SelectItem key={opt} value={opt}>
                  {opt}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select
            value={attendanceDuration || null}
            onValueChange={(v: string | null) =>
              updateParams({
                attendanceDuration: !v || v === "__all__" ? undefined : v,
              })
            }
          >
            <SelectTrigger className="w-[140px] rounded-xl">
              <SelectValue placeholder="Attendance" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__all__">All attendance</SelectItem>
              {attendanceDurationOptions.map((opt) => (
                <SelectItem key={opt} value={opt}>
                  {opt}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select
            value={serviceAttended || null}
            onValueChange={(v: string | null) =>
              updateParams({
                serviceAttended: !v || v === "__all__" ? undefined : v,
              })
            }
          >
            <SelectTrigger className="w-[140px] rounded-xl">
              <SelectValue placeholder="Service" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__all__">All services</SelectItem>
              {serviceAttendedOptions.map((opt) => (
                <SelectItem key={opt} value={opt}>
                  {opt}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {showAssignedToFilter && (
            <Select
              value={assignedToId || null}
              onValueChange={(v: string | null) =>
                updateParams({
                  assignedToId: !v || v === "__all__" ? undefined : v,
                })
              }
            >
              <SelectTrigger className="w-[150px] rounded-xl">
                <SelectValue placeholder="Assigned To" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__all__">All assignees</SelectItem>
                <SelectItem value="me">My Cards</SelectItem>
                <SelectItem value="unassigned">Unassigned</SelectItem>
                {users.map((u) => (
                  <SelectItem key={u.id} value={u.id}>
                    {u.displayName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
        </div>
      </div>

      <div className="flex shrink-0 items-center gap-2">
        {onColumnVisibilityChange && (
          <Popover>
            <PopoverTrigger
              render={
                <Button variant="outline" size="sm" className="rounded-xl" />
              }
            >
              <Columns3 className="size-4" />
              <span className="hidden sm:inline ml-1.5">
                Columns
                <span className="ml-1 text-muted-foreground">({visibleCount})</span>
              </span>
            </PopoverTrigger>
            <PopoverContent side="bottom" align="end" sideOffset={4} className="w-56 p-0">
              <div className="px-3 pt-3 pb-1">
                <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                  Toggle Columns
                </p>
              </div>
              <div className="max-h-[360px] overflow-y-auto px-1 pb-2">
                {COLUMN_GROUPS.map((group) => (
                  <div key={group.label}>
                    <div className="px-2 pt-2 pb-0.5 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/60">
                      {group.label}
                    </div>
                    {group.ids.map((id) => (
                      <label
                        key={id}
                        className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
                      >
                        <Checkbox
                          checked={isVisible(id)}
                          onCheckedChange={(checked) =>
                            toggleCol(id, checked !== false)
                          }
                        />
                        {COL_LABELS[id] ?? id}
                      </label>
                    ))}
                  </div>
                ))}
              </div>
            </PopoverContent>
          </Popover>
        )}

        {onExportCsv && (
          <Button
            variant="outline"
            size="sm"
            className="rounded-xl"
            onClick={onExportCsv}
          >
            <Download className="size-4" />
            <span className="hidden sm:inline ml-1.5">Export</span>
          </Button>
        )}
        {onUploadClick && (
          <Button size="sm" className="rounded-xl" onClick={onUploadClick}>
            <Upload className="size-4" />
            <span className="hidden sm:inline ml-1.5">Upload</span>
          </Button>
        )}
      </div>
    </div>
  );
}
