"use client";

import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  Dialog,
  DialogContent,
  DialogTitle,
  DialogFooter,
  DialogHeader,
  CustomAlertDialog,
  Form,
  FormInput,
  FormMultiComboboxInput,
  Button,
} from "ikoncomponents";
import { Trash2, Pencil, Plus, Save } from "lucide-react";
import { GroupItem } from "@/app/main/planning/projects/types/project";

// --- Zod Schema ---
const taskGroupSchema = z.object({
  groupName: z.string().min(1, "Group name is required"),
  taskIds: z.array(z.string()).min(1, "Select at least one task"),
});
type TaskGroupForm = z.infer<typeof taskGroupSchema>;

const defaultValues: TaskGroupForm = {
  groupName: "",
  taskIds: [],
};

interface TaskGroupModalProps {
  isOpen: boolean;
  onClose: () => void;
  scheduleTaskItems: Array<{ value: string; label: string }>;
  initialGroups: Record<string, GroupItem>;
  onSave: (groups: Record<string, GroupItem>) => void;
}

const TaskGroupModal: React.FC<TaskGroupModalProps> = ({
  isOpen,
  onClose,
  scheduleTaskItems,
  initialGroups,
  onSave,
}) => {
  const [localGroups, setLocalGroups] = useState<Record<string, GroupItem>>(initialGroups || {});
  const [editingGroupId, setEditingGroupId] = useState<string | null>(null);
  const [alertState, setAlertState] = useState<{
    open: boolean;
    title: string;
    description?: string;
    confirmText?: string;
    cancelText?: string;
    onConfirm?: () => void;
    onCancel?: () => void;
  }>({ open: false, title: "" });

  const form = useForm<TaskGroupForm>({
    resolver: zodResolver(taskGroupSchema),
    defaultValues,
  });
  const { reset, setValue, getValues } = form;

  const closeAlert = () => setAlertState(s => ({ ...s, open: false }));
  const showAlert = (title: string, description?: string) =>
    setAlertState({ open: true, title, description, confirmText: "OK", onConfirm: closeAlert });
  const showConfirm = (title: string, description: string, onConfirm: () => void) =>
    setAlertState({ open: true, title, description, confirmText: "Confirm", cancelText: "Cancel", onConfirm: () => { closeAlert(); onConfirm(); }, onCancel: closeAlert });

  // Tasks already assigned to any group OTHER than the one being edited
  const assignedElsewhere = new Set<string>(
    Object.entries(localGroups)
      .filter(([gId]) => gId !== editingGroupId)
      .flatMap(([, g]) => (g.taskIds || []).map(String))
  );

  // Available tasks: exclude those already in another group
  const availableTaskItems = scheduleTaskItems.filter(i => !assignedElsewhere.has(i.value));

  // All available task IDs as strings for "Select All"
  const allTaskValues = availableTaskItems.map(i => i.value);

  // Prepend "Select All" item
  const comboItems = [
    { value: "__ALL__", label: "Select All" },
    ...availableTaskItems,
  ];

  const handleTaskSelect = (values: string[]) => {
    if (values.includes("__ALL__")) {
      const currentIds: string[] = getValues("taskIds") || [];
      const allSelected = allTaskValues.every(id => currentIds.includes(id));
      setValue("taskIds", allSelected ? [] : allTaskValues);
    }
  };

  const handleAddUpdate = () => {
    const values = getValues();
    if (!values.groupName.trim()) {
      showAlert("Validation Error", "Group name is required.");
      return;
    }
    const taskIds = (values.taskIds || []).filter(v => v !== "__ALL__");
    if (taskIds.length === 0) {
      showAlert("Validation Error", "Please select at least one task.");
      return;
    }

    const existingEntry = Object.entries(localGroups).find(
      ([gId, g]) => g.groupName.trim().toLowerCase() === values.groupName.trim().toLowerCase() && gId !== editingGroupId
    );
    if (existingEntry) {
      showAlert("Duplicate Name", `A group named "${values.groupName}" already exists.`);
      return;
    }

    if (editingGroupId) {
      setLocalGroups(prev => ({
        ...prev,
        [editingGroupId]: {
          ...prev[editingGroupId],
          groupName: values.groupName.trim(),
          taskIds: taskIds.map(Number),
        },
      }));
    } else {
      const newId = String(Date.now());
      setLocalGroups(prev => ({
        ...prev,
        [newId]: {
          groupName: values.groupName.trim(),
          taskIds: taskIds.map(Number),
        },
      }));
    }

    setEditingGroupId(null);
    reset(defaultValues);
  };

  const handleEdit = (groupId: string) => {
    const group = localGroups[groupId];
    if (!group) return;
    setEditingGroupId(groupId);
    reset({
      groupName: group.groupName,
      taskIds: (group.taskIds || []).map(String),
    });
  };

  const handleDelete = (groupId: string) => {
    const group = localGroups[groupId];
    showConfirm(
      "Delete Group",
      `Are you sure you want to delete group "${group?.groupName}"?`,
      () => {
        setLocalGroups(prev => {
          const updated = { ...prev };
          delete updated[groupId];
          return updated;
        });
        if (editingGroupId === groupId) {
          setEditingGroupId(null);
          reset(defaultValues);
        }
      }
    );
  };

  const handleClear = () => {
    setEditingGroupId(null);
    reset(defaultValues);
  };

  const handleSave = () => {
    onSave(localGroups);
  };

  const resolveTaskNames = (taskIds: number[]) =>
    taskIds
      .map(id => scheduleTaskItems.find(i => i.value === String(id))?.label || String(id))
      .join(", ");

  const groupEntries = Object.entries(localGroups);

  return (
    <>
      <Dialog open={isOpen} onOpenChange={onClose}>
        <DialogContent
          className="w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto"
          onInteractOutside={(e) => e.preventDefault()}
          onEscapeKeyDown={(e) => e.preventDefault()}
        >
          <DialogHeader>
            <DialogTitle>Create Task Group</DialogTitle>
          </DialogHeader>

          <Form {...form}>
            <form>
              <div className="grid grid-cols-2 gap-4">
                <FormInput
                  formControl={form.control}
                  name="groupName"
                  label="Task Group Name"
                  placeholder="e.g. T1"
                />
                <FormMultiComboboxInput
                  formControl={form.control}
                  name="taskIds"
                  label="Schedule Tasks"
                  placeholder="Select tasks..."
                  items={comboItems}
                  onSelect={handleTaskSelect}
                />
              </div>
            </form>
          </Form>

          <div className="flex gap-2">
            <Button
              variant="outline"
              className="h-8 px-4 text-sm"
              onClick={handleAddUpdate}
            >
              <Plus className="w-3.5 h-3.5 mr-1.5" />
              {editingGroupId ? "Update Group" : "Add Group"}
            </Button>
            {editingGroupId && (
              <Button
                variant="ghost"
                className="h-8 px-4 text-sm"
                onClick={handleClear}
              >
                Cancel
              </Button>
            )}
          </div>

          {groupEntries.length > 0 && (
            <div className="border border-border rounded-md overflow-hidden">
              <table className="w-full text-sm">
                <thead className="bg-muted/50">
                  <tr>
                    <th className="text-left px-3 py-2 font-medium text-muted-foreground w-1/4">Task Group</th>
                    <th className="text-left px-3 py-2 font-medium text-muted-foreground">Schedule Tasks</th>
                    <th className="px-3 py-2 w-20 text-center font-medium text-muted-foreground">Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {groupEntries.map(([groupId, group], index) => (
                    <tr
                      key={groupId}
                      className={`border-t border-border ${editingGroupId === groupId ? "bg-muted/30" : ""} ${index % 2 === 0 ? "" : "bg-muted/10"}`}
                    >
                      <td className="px-3 py-2 font-medium">{group.groupName}</td>
                      <td className="px-3 py-2 text-muted-foreground">
                        {group.taskIds?.length > 0
                          ? resolveTaskNames(group.taskIds)
                          : <span className="italic text-xs">No tasks</span>
                        }
                      </td>
                      <td className="px-3 py-2">
                        <div className="flex items-center justify-center gap-2">
                          <button
                            onClick={() => handleEdit(groupId)}
                            className="text-muted-foreground hover:text-foreground transition-colors"
                            title="Edit"
                          >
                            <Pencil size={15} />
                          </button>
                          <button
                            onClick={() => handleDelete(groupId)}
                            className="text-muted-foreground hover:text-destructive transition-colors"
                            title="Delete"
                          >
                            <Trash2 size={15} />
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}

          {groupEntries.length === 0 && (
            <div className="flex justify-center items-center h-20 text-sm text-muted-foreground border border-dashed border-border rounded-md">
              No groups yet. Add one above.
            </div>
          )}

          <DialogFooter>
            <Button variant="ghost" onClick={onClose} className="h-8 px-4 text-sm">
              Cancel
            </Button>
            <Button variant="outline" onClick={handleSave} className="h-8 px-4 text-sm">
              <Save className="w-3.5 h-3.5 mr-1.5" /> Save Groups
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {alertState.open && (
        <CustomAlertDialog
          title={alertState.title}
          description={alertState.description}
          confirmText={alertState.confirmText}
          cancelText={alertState.cancelText}
          onConfirm={alertState.onConfirm}
          onCancel={alertState.onCancel}
        />
      )}
    </>
  );
};

export default TaskGroupModal;
