"use client";

import * as React from "react";
import {
  CheckCircle,
  ClipboardCopy,
  Download,
  RefreshCw,
  Trash2,
  X,
  LayoutGrid,
  UserPlus,
} from "lucide-react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import { COPYABLE_FIELDS, type ResponseCard } from "./columns";

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

interface SelectionToolbarProps {
  selectedIds: string[];
  selectedRows: ResponseCard[];
  onMarkReviewed?: (ids: string[]) => void;
  onMarkExported?: (ids: string[]) => void;
  onReprocess?: (ids: string[]) => void;
  onSyncMonday?: (ids: string[]) => void;
  onAssign?: (ids: string[], userId: string) => void;
  onDelete?: (ids: string[]) => void;
  onClear: () => void;
}

const DEFAULT_COPY_FIELDS = new Set<string>(["name", "email"]);

function formatFieldValue(value: unknown): string {
  if (value == null) return "";
  if (typeof value === "boolean") return value ? "Yes" : "No";
  if (Array.isArray(value)) return value.filter(Boolean).join(", ");
  if (typeof value === "object") {
    try {
      const arr = Object.values(value).flat().filter(Boolean);
      return arr.join(", ");
    } catch {
      return String(value);
    }
  }
  return String(value);
}

export function SelectionToolbar({
  selectedIds,
  selectedRows,
  onMarkReviewed,
  onMarkExported,
  onReprocess,
  onSyncMonday,
  onAssign,
  onDelete,
  onClear,
}: SelectionToolbarProps) {
  const count = selectedIds.length;
  const [copyFields, setCopyFields] = React.useState<Set<string>>(
    () => new Set(DEFAULT_COPY_FIELDS)
  );
  const [copyOpen, setCopyOpen] = React.useState(false);
  const [assignOpen, setAssignOpen] = React.useState(false);
  const [users, setUsers] = React.useState<AssignableUser[]>([]);

  React.useEffect(() => {
    if (!assignOpen) return;
    fetch("/api/users?role=reviewer")
      .then((r) => r.json())
      .then((data) => {
        const reviewers: AssignableUser[] = data.users || [];
        fetch("/api/users?role=admin")
          .then((r2) => r2.json())
          .then((d2) => {
            const admins: AssignableUser[] = d2.users || [];
            const all = [...admins, ...reviewers];
            const seen = new Set<string>();
            setUsers(all.filter((u) => (seen.has(u.id) ? false : (seen.add(u.id), true))));
          });
      })
      .catch(() => {});
  }, [assignOpen]);

  const toggleCopyField = (field: string) => {
    setCopyFields((prev) => {
      const next = new Set(prev);
      if (next.has(field)) next.delete(field);
      else next.add(field);
      return next;
    });
  };

  const handleCopyToClipboard = async () => {
    const fields = COPYABLE_FIELDS.filter((f) => copyFields.has(f.field));
    if (fields.length === 0) {
      toast.error("Select at least one field to copy");
      return;
    }

    if (fields.length === 1) {
      const field = fields[0];
      const values = selectedRows
        .map((row) => formatFieldValue(row[field.field]))
        .filter(Boolean);
      await navigator.clipboard.writeText(values.join("\n"));
      toast.success(`Copied ${values.length} ${field.label.toLowerCase()} value(s)`);
    } else {
      const header = fields.map((f) => f.label).join("\t");
      const rows = selectedRows.map((row) =>
        fields.map((f) => formatFieldValue(row[f.field])).join("\t")
      );
      await navigator.clipboard.writeText([header, ...rows].join("\n"));
      toast.success(
        `Copied ${selectedRows.length} row(s) with ${fields.length} field(s)`
      );
    }

    setCopyOpen(false);
  };

  return (
    <div
      className={cn(
        "fixed bottom-6 left-1/2 z-50 -translate-x-1/2 transition-all duration-300 ease-out",
        count > 0
          ? "translate-y-0 opacity-100"
          : "pointer-events-none translate-y-4 opacity-0"
      )}
    >
      <div className="glass-card flex items-center gap-2 rounded-2xl px-4 py-2.5 shadow-xl sm:gap-3 sm:px-5">
        <button
          onClick={onClear}
          className="flex shrink-0 items-center gap-1.5 text-sm font-medium hover:text-primary transition-colors"
        >
          {count} selected
          <X className="size-3.5" />
        </button>

        <div className="h-4 w-px bg-border/50" />

        <div className="flex items-center gap-1.5">
          {onMarkReviewed && (
            <Button
              variant="ghost"
              size="sm"
              className="rounded-xl"
              onClick={() => onMarkReviewed(selectedIds)}
            >
              <CheckCircle className="size-4" />
              <span className="hidden sm:inline ml-1">Reviewed</span>
            </Button>
          )}
          {onMarkExported && (
            <Button
              variant="ghost"
              size="sm"
              className="rounded-xl"
              onClick={() => onMarkExported(selectedIds)}
            >
              <Download className="size-4" />
              <span className="hidden sm:inline ml-1">Export</span>
            </Button>
          )}
          {onReprocess && (
            <Button
              variant="ghost"
              size="sm"
              className="rounded-xl"
              onClick={() => onReprocess(selectedIds)}
            >
              <RefreshCw className="size-4" />
              <span className="hidden sm:inline ml-1">Reprocess</span>
            </Button>
          )}
          {onSyncMonday && (
            <Button
              variant="ghost"
              size="sm"
              className="rounded-xl"
              onClick={() => onSyncMonday(selectedIds)}
            >
              <LayoutGrid className="size-4" />
              <span className="hidden sm:inline ml-1">Monday.com</span>
            </Button>
          )}

          {onAssign && (
            <Popover open={assignOpen} onOpenChange={setAssignOpen}>
              <PopoverTrigger
                render={
                  <Button variant="ghost" size="sm" className="rounded-xl" />
                }
              >
                <UserPlus className="size-4" />
                <span className="hidden sm:inline ml-1">Assign</span>
              </PopoverTrigger>
              <PopoverContent side="top" sideOffset={8} className="w-56 p-0">
                <div className="px-3 pt-3 pb-2">
                  <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                    Assign to
                  </p>
                </div>
                <div className="max-h-[200px] overflow-y-auto px-1 pb-2">
                  {users.length === 0 && (
                    <p className="px-3 py-2 text-sm text-muted-foreground">
                      No users available
                    </p>
                  )}
                  {users.map((u) => (
                    <button
                      key={u.id}
                      type="button"
                      className="flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground text-left"
                      onClick={() => {
                        onAssign(selectedIds, u.id);
                        setAssignOpen(false);
                      }}
                    >
                      {u.displayName}
                    </button>
                  ))}
                </div>
              </PopoverContent>
            </Popover>
          )}

          <Popover open={copyOpen} onOpenChange={setCopyOpen}>
            <PopoverTrigger
              render={
                <Button variant="ghost" size="sm" className="rounded-xl" />
              }
            >
              <ClipboardCopy className="size-4" />
              <span className="hidden sm:inline ml-1">Copy</span>
            </PopoverTrigger>
            <PopoverContent
              side="top"
              sideOffset={8}
              className="w-64 p-0"
            >
              <div className="px-3 pt-3 pb-2">
                <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                  What to copy
                </p>
              </div>
              <div className="max-h-[280px] overflow-y-auto px-3 space-y-2">
                {COPYABLE_FIELDS.map(({ field, label }) => (
                  <label
                    key={field}
                    className="flex items-center justify-between cursor-pointer group"
                  >
                    <span className="text-sm group-hover:text-foreground transition-colors">
                      {label}
                    </span>
                    <Switch
                      size="sm"
                      checked={copyFields.has(field)}
                      onCheckedChange={() => toggleCopyField(field)}
                    />
                  </label>
                ))}
              </div>
              <div className="p-3 pt-2">
                <Button
                  size="sm"
                  className="w-full rounded-xl"
                  onClick={handleCopyToClipboard}
                >
                  <ClipboardCopy className="size-3.5 mr-1.5" />
                  Copy to clipboard
                </Button>
              </div>
            </PopoverContent>
          </Popover>
        </div>

        <div className="h-4 w-px bg-border/50" />

        {onDelete && (
          <Button
            variant="ghost"
            size="sm"
            className="rounded-xl text-destructive hover:bg-destructive/10 hover:text-destructive"
            onClick={() => onDelete(selectedIds)}
          >
            <Trash2 className="size-4" />
            <span className="hidden sm:inline ml-1">Delete</span>
          </Button>
        )}
      </div>
    </div>
  );
}
