import { useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { ArrowUpDown, Pencil, Trash2, PlusCircle } from "lucide-react";
import config from "@/config";
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  SortingState,
  flexRender,
  type ColumnDef,
} from "@tanstack/react-table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { toast } from "sonner";

interface FieldOption {
  label: string;
  value: string;
}

interface PromptFormData {
  id?: number;
  prompt_text: string;
  prompt_type: 'general' | 'company_specific' | 'system';
  company: string | null;
}

interface AiPrompt {
  id: number;
  prompt_text: string;
  prompt_type: 'general' | 'company_specific' | 'system';
  company: string | null;
  created_at: string;
  updated_at: string;
}

interface FieldOptions {
  companies: FieldOption[];
}

export function PromptManagement() {
  const [isFormOpen, setIsFormOpen] = useState(false);
  const [isDeleteOpen, setIsDeleteOpen] = useState(false);
  const [promptToDelete, setPromptToDelete] = useState<AiPrompt | null>(null);
  const [editingPrompt, setEditingPrompt] = useState<AiPrompt | null>(null);
  const [sorting, setSorting] = useState<SortingState>([
    { id: "prompt_type", desc: true },
    { id: "company", desc: false }
  ]);
  const [searchQuery, setSearchQuery] = useState("");
  const [formData, setFormData] = useState<PromptFormData>({
    prompt_text: "",
    prompt_type: "general",
    company: null,
  });

  const queryClient = useQueryClient();

  const { data: prompts, isLoading } = useQuery<AiPrompt[]>({
    queryKey: ["ai-prompts"],
    queryFn: async () => {
      const response = await fetch(`${config.apiUrl}/ai-prompts`);
      if (!response.ok) {
        throw new Error("Failed to fetch AI prompts");
      }
      return response.json();
    },
  });

  const { data: fieldOptions } = useQuery<FieldOptions>({
    queryKey: ["fieldOptions"],
    queryFn: async () => {
      const response = await fetch(`${config.apiUrl}/import/field-options`);
      if (!response.ok) {
        throw new Error("Failed to fetch field options");
      }
      return response.json();
    },
  });

  // Check if general and system prompts already exist
  const generalPromptExists = useMemo(() => {
    return prompts?.some(prompt => prompt.prompt_type === 'general');
  }, [prompts]);
  
  const systemPromptExists = useMemo(() => {
    return prompts?.some(prompt => prompt.prompt_type === 'system');
  }, [prompts]);

  const createMutation = useMutation({
    mutationFn: async (data: PromptFormData) => {
      const response = await fetch(`${config.apiUrl}/ai-prompts`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
      });
      
      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.message || error.error || "Failed to create prompt");
      }
      
      return response.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
      toast.success("Prompt created successfully");
      resetForm();
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : "Failed to create prompt");
    },
  });

  const updateMutation = useMutation({
    mutationFn: async (data: PromptFormData) => {
      if (!data.id) throw new Error("Prompt ID is required for update");
      
      const response = await fetch(`${config.apiUrl}/ai-prompts/${data.id}`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
      });
      
      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.message || error.error || "Failed to update prompt");
      }
      
      return response.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
      toast.success("Prompt updated successfully");
      resetForm();
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : "Failed to update prompt");
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: number) => {
      const response = await fetch(`${config.apiUrl}/ai-prompts/${id}`, {
        method: "DELETE",
      });
      if (!response.ok) {
        throw new Error("Failed to delete prompt");
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
      toast.success("Prompt deleted successfully");
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : "Failed to delete prompt");
    },
  });

  const handleEdit = (prompt: AiPrompt) => {
    setEditingPrompt(prompt);
    setFormData({
      id: prompt.id,
      prompt_text: prompt.prompt_text,
      prompt_type: prompt.prompt_type,
      company: prompt.company,
    });
    setIsFormOpen(true);
  };

  const handleDeleteClick = (prompt: AiPrompt) => {
    setPromptToDelete(prompt);
    setIsDeleteOpen(true);
  };

  const handleDeleteConfirm = () => {
    if (promptToDelete) {
      deleteMutation.mutate(promptToDelete.id);
      setIsDeleteOpen(false);
      setPromptToDelete(null);
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    
    // If prompt_type is general or system, ensure company is null
    const submitData = {
      ...formData,
      company: formData.prompt_type === 'company_specific' ? formData.company : null,
    };
    
    if (editingPrompt) {
      updateMutation.mutate(submitData);
    } else {
      createMutation.mutate(submitData);
    }
  };

  const resetForm = () => {
    setFormData({
      prompt_text: "",
      prompt_type: "general",
      company: null,
    });
    setEditingPrompt(null);
    setIsFormOpen(false);
  };

  const handleCreateClick = () => {
    resetForm();
    
    // If general prompt and system prompt exist, default to company-specific
    if (generalPromptExists && systemPromptExists) {
      setFormData(prev => ({
        ...prev,
        prompt_type: 'company_specific'
      }));
    } else if (generalPromptExists && !systemPromptExists) {
      // If general exists but system doesn't, suggest system prompt
      setFormData(prev => ({
        ...prev,
        prompt_type: 'system'
      }));
    } else if (!generalPromptExists) {
      // If no general prompt, suggest that first
      setFormData(prev => ({
        ...prev,
        prompt_type: 'general'
      }));
    }
    
    setIsFormOpen(true);
  };

  const columns = useMemo<ColumnDef<AiPrompt>[]>(() => [
    {
      accessorKey: "prompt_type",
      header: ({ column }) => (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
        >
          Type
          <ArrowUpDown className="ml-2 h-4 w-4" />
        </Button>
      ),
      cell: ({ row }) => {
        const type = row.getValue("prompt_type") as string;
        if (type === 'general') return 'General';
        if (type === 'system') return 'System';
        return 'Company Specific';
      },
    },
    {
      accessorFn: (row) => row.prompt_text.length,
      id: "length",
      header: ({ column }) => (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
        >
          Length
          <ArrowUpDown className="ml-2 h-4 w-4" />
        </Button>
      ),
      cell: ({ getValue }) => {
        const length = getValue() as number;
        return <span>{length.toLocaleString()}</span>;
      },
    },
    {
      accessorKey: "company",
      header: ({ column }) => (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
        >
          Company
          <ArrowUpDown className="ml-2 h-4 w-4" />
        </Button>
      ),
      cell: ({ row }) => {
        const companyId = row.getValue("company");
        if (!companyId) return 'N/A';
        return fieldOptions?.companies.find(c => c.value === companyId)?.label || companyId;
      },
    },
    {
      accessorKey: "updated_at",
      header: ({ column }) => (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
        >
          Last Updated
          <ArrowUpDown className="ml-2 h-4 w-4" />
        </Button>
      ),
      cell: ({ row }) => new Date(row.getValue("updated_at")).toLocaleDateString(),
    },
    {
      id: "actions",
      cell: ({ row }) => (
        <div className="flex gap-2 justify-end pr-4">
          <Button
            variant="ghost"
            onClick={() => handleEdit(row.original)}
          >
            <Pencil className="h-4 w-4" />
            Edit
          </Button>
          <Button
            variant="ghost"
            className="text-destructive hover:text-destructive"
            onClick={() => handleDeleteClick(row.original)}
          >
            <Trash2 className="h-4 w-4" />
            Delete
          </Button>
        </div>
      ),
    },
  ], [fieldOptions]);

  const filteredData = useMemo(() => {
    if (!prompts) return [];
    return prompts.filter((prompt) => {
      const searchString = searchQuery.toLowerCase();
      return (
        prompt.prompt_type.toLowerCase().includes(searchString) ||
        (prompt.company && prompt.company.toLowerCase().includes(searchString))
      );
    });
  }, [prompts, searchQuery]);

  const table = useReactTable({
    data: filteredData,
    columns,
    state: {
      sorting,
    },
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h2 className="text-2xl font-bold">AI Validation Prompts</h2>
        <Button onClick={handleCreateClick}>
          <PlusCircle className="mr-2 h-4 w-4" />
          Create New Prompt
        </Button>
      </div>

      <div className="flex items-center gap-4">
        <Input
          placeholder="Search prompts..."
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          className="max-w-sm"
        />
      </div>

      {isLoading ? (
        <div>Loading prompts...</div>
      ) : (
        <div className="border rounded-lg">
          <Table>
            <TableHeader className="bg-muted">
              {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="hover:bg-gray-100">
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id} className="pl-6">
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={columns.length} className="text-center">
                    No prompts found
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      )}

      {/* Prompt Form Dialog */}
      <Dialog open={isFormOpen} onOpenChange={setIsFormOpen}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>{editingPrompt ? "Edit Prompt" : "Create New Prompt"}</DialogTitle>
            <DialogDescription>
              {editingPrompt 
                ? "Update this AI validation prompt."
                : "Create a new AI validation prompt that will be used during product validation."}
            </DialogDescription>
          </DialogHeader>
          
          <form onSubmit={handleSubmit}>
            <div className="grid gap-4 py-4">
              <div className="grid gap-2">
                <Label htmlFor="prompt_type">Prompt Type</Label>
                <Select
                  value={formData.prompt_type}
                  onValueChange={(value: 'general' | 'company_specific' | 'system') => 
                    setFormData({ ...formData, prompt_type: value })
                  }
                  disabled={(generalPromptExists && formData.prompt_type !== 'general' && !editingPrompt?.id) || 
                           (systemPromptExists && formData.prompt_type !== 'system' && !editingPrompt?.id)}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select prompt type" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem 
                      value="general" 
                      disabled={generalPromptExists && !editingPrompt?.prompt_type?.includes('general')}
                    >
                      General
                    </SelectItem>
                    <SelectItem 
                      value="system" 
                      disabled={systemPromptExists && !editingPrompt?.prompt_type?.includes('system')}
                    >
                      System
                    </SelectItem>
                    <SelectItem value="company_specific">Company Specific</SelectItem>
                  </SelectContent>
                </Select>
                {generalPromptExists && formData.prompt_type !== 'general' && !editingPrompt?.id && systemPromptExists && formData.prompt_type !== 'system' && (
                  <p className="text-xs text-muted-foreground">
                    General and system prompts already exist. You can only create company-specific prompts.
                  </p>
                )}
                {generalPromptExists && !systemPromptExists && formData.prompt_type !== 'general' && !editingPrompt?.id && (
                  <p className="text-xs text-muted-foreground">
                    A general prompt already exists. You can create a system prompt or company-specific prompts.
                  </p>
                )}
                {systemPromptExists && !generalPromptExists && formData.prompt_type !== 'system' && !editingPrompt?.id && (
                  <p className="text-xs text-muted-foreground">
                    A system prompt already exists. You can create a general prompt or company-specific prompts.
                  </p>
                )}
              </div>
              
              {formData.prompt_type === 'company_specific' && (
                <div className="grid gap-2">
                  <Label htmlFor="company">Company</Label>
                  <Select
                    value={formData.company || ''}
                    onValueChange={(value) => setFormData({ ...formData, company: value })}
                    required={formData.prompt_type === 'company_specific'}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Select company" />
                    </SelectTrigger>
                    <SelectContent>
                      {fieldOptions?.companies.map((company) => (
                        <SelectItem key={company.value} value={company.value}>
                          {company.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}
              
              <div className="grid gap-2">
                <Label htmlFor="prompt_text">Prompt Text</Label>
                <Textarea
                  id="prompt_text"
                  value={formData.prompt_text}
                  onChange={(e) => setFormData({ ...formData, prompt_text: e.target.value })}
                  placeholder={`Enter your ${formData.prompt_type === 'system' ? 'system instructions' : 'validation prompt'} text...`}
                  className="h-80 font-mono text-sm"
                  required
                />
                {formData.prompt_type === 'system' && (
                  <p className="text-xs text-muted-foreground mt-1">
                    System prompts provide the initial instructions to the AI. This sets the tone and approach for all validations.
                  </p>
                )}
              </div>
            </div>
            
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => {
                resetForm();
                setIsFormOpen(false);
              }}>
                Cancel
              </Button>
              <Button type="submit">
                {editingPrompt ? "Update" : "Create"} Prompt
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <AlertDialog open={isDeleteOpen} onOpenChange={setIsDeleteOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Prompt</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete this prompt? This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={() => {
              setIsDeleteOpen(false);
              setPromptToDelete(null);
            }}>
              Cancel
            </AlertDialogCancel>
            <AlertDialogAction onClick={handleDeleteConfirm}>
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
} 