import type {
  Etape,
  KanbanTask,
  KanbanTaskInsert,
  KanbanTaskUpdate,
  TaskStatus,
} from "@xtablo/shared-types";
import { Button } from "@xtablo/ui/components/button";
import { DatePicker } from "@xtablo/ui/components/date-picker";
import { Input } from "@xtablo/ui/components/input";
import { Label } from "@xtablo/ui/components/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@xtablo/ui/components/select";
import { Textarea } from "@xtablo/ui/components/textarea";
import { TypographyH2 } from "@xtablo/ui/components/typography";
import { X } from "lucide-react";
import { useEffect, useState } from "react";
import type { TabloMember } from "./types";

/** Minimal UserTablo shape needed by this modal (tablo selector when creating). */
interface MinimalTablo {
  id: string;
  name: string;
  color?: string | null;
}

interface TaskModalProps {
  isOpen: boolean;
  tabloId?: string;
  taskId?: string | undefined;
  onClose: () => void;
  /** Task data when editing an existing task. */
  task?: KanbanTask | null;
  members?: TabloMember[];
  etapes?: Etape[];
  initialStatus?: TaskStatus;
  tablos?: MinimalTablo[];
  allowTabloSelection?: boolean;
  initialDueDate?: Date;
  defaultAssigneeId?: string;
  /** Called when creating a new task. */
  onCreateTask?: (task: KanbanTaskInsert) => void;
  /** Called when updating an existing task. */
  onUpdateTask?: (task: KanbanTaskUpdate & { id: string; tablo_id: string }) => void;
  /** Called when deleting an existing task. */
  onDeleteTask?: (taskId: string) => void;
}

export const TaskModal = ({
  tabloId: initialTabloId,
  taskId,
  isOpen,
  onClose,
  task = null,
  members: providedMembers = [],
  initialStatus = "todo",
  etapes: providedEtapes = [],
  tablos,
  allowTabloSelection = false,
  initialDueDate,
  defaultAssigneeId,
  onCreateTask,
  onUpdateTask,
}: TaskModalProps) => {
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [assigneeId, setAssigneeId] = useState<string>("unassigned");
  const [etapeId, setEtapeId] = useState<string>("none");
  const [dueDate, setDueDate] = useState<Date | undefined>(undefined);
  const [selectedTabloId, setSelectedTabloId] = useState<string>(
    initialTabloId || tablos?.[0]?.id || ""
  );

  const currentTabloId = allowTabloSelection ? selectedTabloId : initialTabloId || "";
  const selectedAssigneeLabel =
    assigneeId === "unassigned"
      ? "Non assigné"
      : (providedMembers.find((member) => member.id === assigneeId)?.name ?? "Non assigné");
  const selectedEtapeLabel =
    etapeId === "none"
      ? "Aucune Étape"
      : (providedEtapes.find((etape) => etape.id === etapeId)?.title ?? "Aucune Étape");

  useEffect(() => {
    if (!isOpen) {
      return;
    }

    if (task) {
      setTitle(task.title ?? "");
      setDescription(task.description ?? "");
      setAssigneeId(task.assignee_id ?? "unassigned");
      setEtapeId(task.parent_task_id ?? "none");
      setDueDate(task.due_date ? new Date(task.due_date) : undefined);
      if (!initialTabloId && task.tablo_id) {
        setSelectedTabloId(task.tablo_id);
      }
    } else {
      setTitle("");
      setDescription("");
      setAssigneeId(defaultAssigneeId ?? "unassigned");
      setEtapeId("none");
      setDueDate(initialDueDate ? new Date(initialDueDate) : undefined);
      if (allowTabloSelection && tablos && tablos.length > 0) {
        setSelectedTabloId(tablos[0].id);
      }
    }
  }, [
    isOpen,
    task,
    initialTabloId,
    allowTabloSelection,
    tablos,
    initialDueDate,
    defaultAssigneeId,
  ]);

  // Format Date to YYYY-MM-DD string for database storage
  const formatDateForDb = (date: Date | undefined): string | null => {
    if (!date) return null;
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!title.trim()) return;
    if (!currentTabloId) return;

    const dueDateValue = formatDateForDb(dueDate);

    if (taskId && task) {
      onUpdateTask?.({
        tablo_id: task.tablo_id,
        id: task.id,
        title: title.trim(),
        description: description.trim(),
        assignee_id: assigneeId !== "unassigned" ? assigneeId : undefined,
        status: initialStatus,
        parent_task_id: etapeId !== "none" ? etapeId : null,
        due_date: dueDateValue,
      });
    } else {
      onCreateTask?.({
        tablo_id: currentTabloId,
        title: title.trim(),
        description: description.trim(),
        assignee_id: assigneeId !== "unassigned" ? assigneeId : undefined,
        status: initialStatus,
        parent_task_id: etapeId !== "none" ? etapeId : null,
        due_date: dueDateValue,
      });
    }
    // Reset form
    setTitle("");
    setDescription("");
    setAssigneeId("unassigned");
    setEtapeId("none");
    setDueDate(undefined);
    onClose();
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50">
      <div className="bg-card border border-border rounded-t-2xl sm:rounded-lg p-4 sm:p-6 w-full sm:max-w-md shadow-xl max-h-[90vh] overflow-y-auto">
        {/* Header */}
        <div className="flex items-center justify-between mb-4">
          <TypographyH2 className="text-xl font-bold text-foreground">
            {taskId ? "Modifier la tâche" : "Créer une tâche"}
          </TypographyH2>
          <button
            onClick={onClose}
            className="text-muted-foreground hover:text-foreground transition-colors p-2 -m-2 min-h-[44px] min-w-[44px] flex items-center justify-center"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Form */}
        <form onSubmit={handleSubmit} className="space-y-4">
          {/* Tablo Selection - only show when creating and allowTabloSelection is true */}
          {allowTabloSelection && !taskId && tablos && tablos.length > 0 && (
            <div className="space-y-2">
              <Label htmlFor="tablo">Tablo *</Label>
              <Select value={selectedTabloId} onValueChange={setSelectedTabloId}>
                <SelectTrigger id="tablo" className="w-full">
                  <SelectValue placeholder="Sélectionner un tablo" />
                </SelectTrigger>
                <SelectContent>
                  {tablos.map((tablo) => (
                    <SelectItem key={tablo.id} value={tablo.id}>
                      <div className="flex items-center gap-2">
                        <div
                          className={`w-2 h-2 rounded-full ${tablo.color || "bg-muted-foreground"}`}
                        />
                        {tablo.name}
                      </div>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          )}

          {/* Title */}
          <div className="space-y-2">
            <Label htmlFor="title">Titre *</Label>
            <Input
              id="title"
              type="text"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="Titre de la tâche"
              required
            />
          </div>

          {/* Description */}
          <div className="space-y-2">
            <Label htmlFor="description">Description</Label>
            <Textarea
              id="description"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Description de la tâche"
              className="min-h-[100px]"
            />
          </div>

          {/* Due Date */}
          <div className="space-y-2">
            <Label>Échéance</Label>
            <DatePicker value={dueDate} onChange={setDueDate} placeholder="Choisir une date" />
          </div>

          {/* Assignee */}
          <div className="space-y-2">
            <Label htmlFor="assignee">Assigné à</Label>
            <Select
              value={assigneeId}
              onValueChange={(value) => {
                if (!value) return;
                setAssigneeId(value);
              }}
            >
              <SelectTrigger id="assignee" className="w-full">
                <span className="line-clamp-1">{selectedAssigneeLabel}</span>
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="unassigned">Non assigné</SelectItem>
                {providedMembers.map((member) => (
                  <SelectItem key={member.id} value={member.id}>
                    {member.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* Étape */}
          {providedEtapes.length > 0 && (
            <div className="space-y-2">
              <Label htmlFor="etape">Étape</Label>
              <Select
                value={etapeId}
                onValueChange={(value) => {
                  if (!value) return;
                  setEtapeId(value);
                }}
              >
                <SelectTrigger id="etape" className="w-full">
                  <span className="line-clamp-1">{selectedEtapeLabel}</span>
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">Aucune</SelectItem>
                  {providedEtapes.map((etape) => (
                    <SelectItem key={etape.id} value={etape.id}>
                      {etape.title}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          )}

          {/* Actions */}
          <div className="flex justify-end gap-2 pt-4">
            <Button type="button" variant="ghost" onClick={onClose}>
              Annuler
            </Button>
            <Button type="submit">{taskId ? "Modifier" : "Créer"}</Button>
          </div>
        </form>
      </div>
    </div>
  );
};
