import { useMemo, useRef, useState } from 'react';
import { Check, Copy, Edit2, Lock, Trash2, Upload, X } from 'lucide-react';
import { createColumnHelper, flexRender, useTable } from '@tanstack/react-table';
import { Button } from '@/components/ui/button.js';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog.js';
import { Input } from '@/components/ui/input.js';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table.js';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/tooltip.js';
import { tableFeaturesConfig, type TableFeaturesConfig } from '@/lib/table-features.js';
import { type Template } from '../utils/types.js';

interface TemplateManagerProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  templates: Template[];
  onLoad: (template: Template) => void;
  onRename: (template: Template, newName: string) => void;
  onDuplicate: (template: Template) => void;
  onDelete: (template: Template) => void;
}

const columnHelper = createColumnHelper<TableFeaturesConfig, Template>();

export function TemplateManager({
  open,
  onOpenChange,
  templates,
  onLoad,
  onRename,
  onDuplicate,
  onDelete,
}: TemplateManagerProps) {
  const [globalFilter, setGlobalFilter] = useState('');
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editingName, setEditingName] = useState('');
  const editInputRef = useRef<HTMLInputElement>(null);

  function startEditing(template: Template) {
    setEditingId(template.id);
    setEditingName(template.name);
    // Focus the input on the next tick after render
    setTimeout(() => editInputRef.current?.focus(), 0);
  }

  function cancelEditing() {
    setEditingId(null);
    setEditingName('');
  }

  function submitEditing(template: Template) {
    const trimmed = editingName.trim();
    if (trimmed && trimmed !== template.name) {
      onRename(template, trimmed);
    }
    setEditingId(null);
    setEditingName('');
  }

  const columns = useMemo(
    () =>
      columnHelper.columns([
        columnHelper.accessor('name', {
          header: 'Name',
          cell: info => {
            const template = info.row.original;
            if (editingId === template.id) {
              return (
                <div className="flex items-center gap-1">
                  <Input
                    ref={editInputRef}
                    value={editingName}
                    onChange={e => setEditingName(e.target.value)}
                    onKeyDown={e => {
                      if (e.key === 'Enter') submitEditing(template);
                      if (e.key === 'Escape') cancelEditing();
                    }}
                    className="h-7 text-sm"
                  />
                  <Button
                    variant="ghost"
                    size="sm"
                    className="size-7 p-0 text-green-600 hover:text-green-700"
                    onClick={() => submitEditing(template)}
                    disabled={!editingName.trim()}
                  >
                    <Check className="size-3.5" />
                  </Button>
                  <Button variant="ghost" size="sm" className="size-7 p-0" onClick={cancelEditing}>
                    <X className="size-3.5" />
                  </Button>
                </div>
              );
            }
            return <span className="font-medium">{info.getValue()}</span>;
          },
        }),
        columnHelper.accessor('lastUpdated', {
          header: 'Last Updated',
          cell: info => {
            const date = info.getValue();
            return (
              <span className="text-muted-foreground text-sm">
                {date.toLocaleDateString('en-US', {
                  year: 'numeric',
                  month: 'short',
                  day: 'numeric',
                })}
              </span>
            );
          },
        }),
        columnHelper.accessor('isLocked', {
          header: 'Locked',
          cell: info =>
            info.getValue() ? (
              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger>
                    <Lock className="size-4 text-muted-foreground" />
                  </TooltipTrigger>
                  <TooltipContent>This template is locked</TooltipContent>
                </Tooltip>
              </TooltipProvider>
            ) : null,
        }),
        columnHelper.display({
          id: 'actions',
          header: 'Actions',
          cell: info => {
            const template = info.row.original;
            const isEditing = editingId === template.id;
            return (
              <div className="flex items-center gap-1">
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="size-8 p-0"
                        onClick={() => {
                          onLoad(template);
                          onOpenChange(false);
                        }}
                        disabled={isEditing}
                      >
                        <Upload className="size-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>
                      {template.isLocked ? 'Load template (read-only)' : 'Load template'}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>

                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="size-8 p-0"
                        onClick={() => startEditing(template)}
                        disabled={template.isLocked || isEditing}
                      >
                        <Edit2 className="size-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>
                      {template.isLocked ? 'Cannot rename locked template' : 'Rename template'}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>

                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="size-8 p-0"
                        onClick={() => onDuplicate(template)}
                        disabled={isEditing}
                      >
                        <Copy className="size-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>Duplicate template</TooltipContent>
                  </Tooltip>
                </TooltipProvider>

                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="size-8 p-0 text-destructive hover:text-destructive"
                        onClick={() => onDelete(template)}
                        disabled={template.isLocked || isEditing}
                      >
                        <Trash2 className="size-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>
                      {template.isLocked ? 'Cannot delete locked template' : 'Delete template'}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
              </div>
            );
          },
        }),
      ]),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [onLoad, onRename, onDuplicate, onDelete, onOpenChange, editingId, editingName],
  );

  const table = useTable({
    features: tableFeaturesConfig,
    data: templates,
    columns,
    state: {
      globalFilter,
    },
    onGlobalFilterChange: setGlobalFilter,
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Template Manager</DialogTitle>
          <DialogDescription>Select a template to load, duplicate, or delete.</DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          <Input
            placeholder="Filter templates..."
            value={globalFilter}
            onChange={e => setGlobalFilter(e.target.value)}
            className="max-w-sm"
          />

          <div className="rounded-md border">
            <Table>
              <TableHeader>
                {table.getHeaderGroups().map(headerGroup => (
                  <TableRow key={headerGroup.id}>
                    {headerGroup.headers.map(header => (
                      <TableHead key={header.id}>
                        {header.isPlaceholder
                          ? null
                          : flexRender(header.column.columnDef.header, header.getContext())}
                      </TableHead>
                    ))}
                  </TableRow>
                ))}
              </TableHeader>
              <TableBody>
                {table.getRowModel().rows.length ? (
                  table.getRowModel().rows.map(row => (
                    <TableRow key={row.id} className={row.original.isLocked ? 'bg-muted/30' : ''}>
                      {row.getVisibleCells().map(cell => (
                        <TableCell key={cell.id}>
                          {flexRender(cell.column.columnDef.cell, cell.getContext())}
                        </TableCell>
                      ))}
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell
                      colSpan={columns.length}
                      className="h-24 text-center text-muted-foreground"
                    >
                      No templates found.
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
