"use client";

import * as React from "react";
import { Table } from "@tanstack/react-table";
import { useSession } from "next-auth/react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Bookmark, Save, Trash2 } from "lucide-react";
import {
  getPresets,
  savePreset,
  deletePreset,
} from "./preset-actions";
import { Preset } from "./preset-types";
import { toast } from "sonner"; 

interface ClientTablePresetProps<TData> {
  table: Table<TData>;
  tableKey: string;
}

export function ClientTablePreset<TData>({
  table,
  tableKey,
}: ClientTablePresetProps<TData>) {
  const { data: session } = useSession();
  const [savedPresets, setSavedPresets] = React.useState<Preset[]>([]);
  const [isPresetDialogOpen, setIsPresetDialogOpen] = React.useState(false);
  const [newPresetName, setNewPresetName] = React.useState("");
  const [isLoading, setIsLoading] = React.useState(false);

  const fetchSettings = React.useCallback(async () => {
    const userIdVal = session?.user?.id;
    if (!userIdVal) return;
    
    const userId = Number(userIdVal); 
    if (isNaN(userId)) return;

    const res = await getPresets(tableKey, userId);
    if (res.success && res.data) {
      setSavedPresets(res.data);
    }
  }, [session, tableKey]);

  React.useEffect(() => {
    if (session) {
      fetchSettings();
    }
  }, [fetchSettings, session]);

  const handleSavePreset = async () => {
    const userIdVal = session?.user?.id;
    if (!newPresetName.trim() || !userIdVal) return;
    const userId = Number(userIdVal);
    if (isNaN(userId)) return;

    setIsLoading(true);
    const state = table.getState();
    const settingToSave = {
      sorting: state.sorting,
      columnFilters: state.columnFilters,
      globalFilter: state.globalFilter,
      columnVisibility: state.columnVisibility,
      columnPinning: state.columnPinning,
      columnOrder: state.columnOrder,
      grouping: state.grouping,
      pagination: { pageSize: state.pagination.pageSize }, 
    };

    const res = await savePreset(userId, tableKey, newPresetName, settingToSave);
    setIsLoading(false);

    if (res.success) {
      toast.success("Preset saved successfully");
      setIsPresetDialogOpen(false);
      setNewPresetName("");
      fetchSettings();
    } else {
      toast.error("Failed to save preset");
    }
  };

  const handleLoadPreset = (preset: Preset) => {
    const s = preset.setting as Record<string, any>;
    if (!s) return;

    if (s.sorting) table.setSorting(s.sorting);
    if (s.columnFilters) table.setColumnFilters(s.columnFilters);
    if (s.globalFilter !== undefined) table.setGlobalFilter(s.globalFilter);
    if (s.columnVisibility) table.setColumnVisibility(s.columnVisibility);
    if (s.columnPinning) table.setColumnPinning(s.columnPinning);
    if (s.columnOrder) table.setColumnOrder(s.columnOrder);
    if (s.grouping) table.setGrouping(s.grouping);
    if (s.pagination?.pageSize) table.setPageSize(s.pagination.pageSize);
    
    toast.success(`Preset "${preset.name}" loaded`);
  };

  const handleDeletePreset = async (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    if (!confirm("Are you sure you want to delete this preset?")) return;

    const res = await deletePreset(id);
    if (res.success) {
      toast.success("Preset deleted");
      fetchSettings();
    } else {
      toast.error("Failed to delete preset");
    }
  };

  if (!session) return null;

  return (
    <>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="outline" size="sm" className="ml-2 hidden h-8 lg:flex">
              <Bookmark className="mr-2 h-4 w-4" />
              Presets
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" className="w-[200px]">
            <DropdownMenuLabel>Saved Presets</DropdownMenuLabel>
            <DropdownMenuSeparator />
            {savedPresets.length === 0 ? (
                <div className="p-2 text-sm text-muted-foreground text-center">No saved presets</div>
            ) : (
                savedPresets.map((preset) => (
                    <DropdownMenuItem key={preset.id} onClick={() => handleLoadPreset(preset)} className="flex justify-between cursor-pointer">
                        <span className="truncate flex-1">{preset.name}</span>
                        <Button variant="ghost" size="icon" className="h-4 w-4" onClick={(e) => handleDeletePreset(e, preset.id)}>
                            <Trash2 className="h-3 w-3 text-destructive" />
                        </Button>
                    </DropdownMenuItem>
                ))
            )}
            <DropdownMenuSeparator />
            <DropdownMenuItem onClick={() => setIsPresetDialogOpen(true)} className="cursor-pointer">
                <Save className="mr-2 h-4 w-4" />
                Save Current Preset
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>

        <Dialog open={isPresetDialogOpen} onOpenChange={setIsPresetDialogOpen}>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>Save Preset</DialogTitle>
                    <DialogDescription>
                        Save the current table configuration as a preset.
                    </DialogDescription>
                </DialogHeader>
                <div className="grid gap-4 py-4">
                    <Input 
                        placeholder="Preset Name" 
                        value={newPresetName} 
                        onChange={(e) => setNewPresetName(e.target.value)}
                    />
                </div>
                <DialogFooter>
                    <Button variant="outline" onClick={() => setIsPresetDialogOpen(false)}>Cancel</Button>
                    <Button onClick={handleSavePreset} disabled={isLoading}>Save</Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    </>
  );
}
