"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { Avatar } from "@/components/ui/Avatar";
import { Icon } from "@/components/ui/Icon";
import { Swatches } from "@/components/ui/Swatches";
import { DatePicker } from "@/components/ui/DatePicker";
import { confirmDialog } from "@/components/ui/Dialog";
import {
  createTaskAction,
  updateTaskAction,
  deleteTaskAction,
  addCommentAction,
  deleteCommentAction,
} from "@/lib/kanban/actions";
import type { TaskDTO, TaskCommentDTO } from "@/lib/kanban/queries";
import type { Priority } from "@prisma/client";

export type BoardOptions = {
  users: { id: string; name: string; avatarUrl: string | null }[];
  projects: { id: string; name: string }[];
  labels: { id: string; name: string; color: string }[];
};

const PRIORITY_LABEL: Record<Priority, string> = {
  LOW: "Niedrig",
  MEDIUM: "Mittel",
  HIGH: "Hoch",
  URGENT: "Dringend",
};

type Props = {
  mode: "create" | "edit";
  boardId: string;
  columnId?: string;
  task?: TaskDTO;
  options: BoardOptions;
  canUse: boolean;
  canComment: boolean;
  canManageBoard: boolean;
  currentUserId: string;
  onClose: () => void;
  onSaved: (task: TaskDTO, mode: "create" | "edit") => void;
  onDeleted: (id: string) => void;
};

function fmtTime(iso: string): string {
  return new Date(iso).toLocaleString("de-DE", { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" });
}

export function TaskDrawer({
  mode,
  columnId,
  task,
  options,
  canUse,
  canComment,
  canManageBoard,
  currentUserId,
  onClose,
  onSaved,
  onDeleted,
}: Props) {
  const [title, setTitle] = useState(task?.title ?? "");
  const [description, setDescription] = useState(task?.description ?? "");
  const [priority, setPriority] = useState<Priority>(task?.priority ?? "MEDIUM");
  const [assigneeIds, setAssigneeIds] = useState<string[]>(task?.assignees.map((a) => a.id) ?? []);
  const [projectId, setProjectId] = useState(task?.projectId ?? "");
  const [deadline, setDeadline] = useState(task?.deadline ? task.deadline.slice(0, 10) : "");
  const [labelIds, setLabelIds] = useState<string[]>(task?.labels.map((l) => l.id) ?? []);
  const labels = options.labels;
  const [color, setColor] = useState<string | null>(task?.color ?? null);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [comments, setComments] = useState<TaskCommentDTO[]>([]);
  const [commentText, setCommentText] = useState("");

  useEffect(() => {
    if (mode === "edit" && task) {
      fetch(`/api/kanban/tasks/${task.id}/comments`, { cache: "no-store" })
        .then((r) => (r.ok ? r.json() : { comments: [] }))
        .then((d) => setComments(d.comments ?? []))
        .catch(() => {});
    }
  }, [mode, task]);

  const toggle = (arr: string[], id: string) =>
    arr.includes(id) ? arr.filter((x) => x !== id) : [...arr, id];

  // ── Checkliste aus der Beschreibung ──
  const checkItems = useMemo(() => {
    return description
      .split("\n")
      .map((line, idx) => {
        const m = line.match(/^\s*[-*]\s*\[( |x|X)\]\s?(.*)$/);
        return m ? { idx, checked: m[1].toLowerCase() === "x", label: m[2] } : null;
      })
      .filter((x): x is { idx: number; checked: boolean; label: string } => x !== null);
  }, [description]);
  const checkDone = checkItems.filter((c) => c.checked).length;

  const toggleCheck = (idx: number) => {
    const lines = description.split("\n");
    lines[idx] = lines[idx].replace(/\[( |x|X)\]/, (_m, g) => (String(g).toLowerCase() === "x" ? "[ ]" : "[x]"));
    setDescription(lines.join("\n"));
  };
  const addCheckpoint = () => {
    setDescription((prev) => (prev.trim() ? `${prev.replace(/\s*$/, "")}\n` : "") + "- [ ] Neuer Punkt");
  };

  const save = async () => {
    if (!canUse) return;
    setSaving(true);
    setError(null);
    const payload = {
      title,
      description,
      priority,
      assigneeIds,
      projectId: projectId || null,
      deadline: deadline || null,
      labelIds,
      color,
    };
    const res =
      mode === "create"
        ? await createTaskAction({ columnId: columnId!, ...payload })
        : await updateTaskAction(task!.id, payload);
    setSaving(false);
    if (res.error || !res.task) {
      setError(res.error ?? "Fehler.");
      return;
    }
    onSaved(res.task, mode);
  };

  const remove = async () => {
    if (!task) return;
    if (!(await confirmDialog({ title: "Aufgabe löschen?", message: `„${task.title}“ wird dauerhaft entfernt.`, danger: true }))) return;
    setSaving(true);
    const res = await deleteTaskAction(task.id);
    setSaving(false);
    if (res.error) return setError(res.error);
    onDeleted(task.id);
  };

  const submitComment = async () => {
    if (!task || !commentText.trim()) return;
    const res = await addCommentAction(task.id, commentText);
    if (res.comment) {
      setComments((c) => [...c, res.comment!]);
      setCommentText("");
    }
  };
  const removeComment = async (c: TaskCommentDTO) => {
    if (!(await confirmDialog({ title: "Kommentar löschen?", danger: true }))) return;
    setComments((cs) => cs.filter((x) => x.id !== c.id));
    await deleteCommentAction(c.id);
  };

  return (
    <div className="drawer-overlay" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className="drawer animate-in">
        <div className="mb-5 flex items-center justify-between">
          <span className="eyebrow">{mode === "create" ? "Neue Aufgabe" : "Aufgabe"}</span>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Schließen">
            <Icon name="close" size={16} />
          </button>
        </div>

        {error ? <p className="field-error mb-3">{error}</p> : null}

        <div className="flex flex-col gap-4">
          <div className="field">
            <label className="label">Titel</label>
            <input className="input" value={title} onChange={(e) => setTitle(e.target.value)} disabled={!canUse} placeholder="Was ist zu tun?" />
          </div>

          <div className="field">
            <div className="flex items-center justify-between">
              <label className="label">Beschreibung &amp; Checkliste</label>
              {canUse ? (
                <button className="pill btn-sm" onClick={addCheckpoint} type="button">
                  <Icon name="check" size={14} /> Checkpunkt
                </button>
              ) : null}
            </div>
            <textarea
              className="textarea"
              style={{ minHeight: 90 }}
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              disabled={!canUse}
              placeholder={"Details …\n- [ ] Aufgabe zum Abhaken"}
            />
            {checkItems.length > 0 ? (
              <div className="mt-2 flex flex-col gap-1.5">
                <div className="flex items-center gap-2 text-xs text-muted">
                  <span className="font-bold">{checkDone}/{checkItems.length} erledigt</span>
                  <span className="h-1.5 flex-1 overflow-hidden rounded-full" style={{ background: "var(--line)" }}>
                    <span className="block h-full rounded-full" style={{ width: `${checkItems.length ? (checkDone / checkItems.length) * 100 : 0}%`, background: "var(--grad-brand)" }} />
                  </span>
                </div>
                {checkItems.map((c) => (
                  <button
                    key={c.idx}
                    type="button"
                    onClick={() => canUse && toggleCheck(c.idx)}
                    className="flex items-center gap-2 rounded-lg px-2 py-1 text-left text-sm hover:bg-[rgba(158,215,255,.06)]"
                  >
                    <span className="grid h-4 w-4 shrink-0 place-items-center rounded" style={{ background: c.checked ? "var(--grad-brand)" : "transparent", border: c.checked ? "none" : "1px solid var(--line-strong)", color: "#0a0e22" }}>
                      {c.checked ? <Icon name="check" size={11} /> : null}
                    </span>
                    <span style={{ textDecoration: c.checked ? "line-through" : "none", opacity: c.checked ? 0.6 : 1 }}>{c.label || "…"}</span>
                  </button>
                ))}
              </div>
            ) : null}
          </div>

          <div className="field">
            <label className="label">Priorität</label>
            <div className="flex flex-wrap gap-2">
              {(Object.keys(PRIORITY_LABEL) as Priority[]).map((p) => (
                <button key={p} type="button" className="pill" data-active={priority === p} onClick={() => canUse && setPriority(p)}>
                  {PRIORITY_LABEL[p]}
                </button>
              ))}
            </div>
          </div>

          <div className="field">
            <label className="label">Kartenfarbe</label>
            <Swatches value={color} allowNone onChange={(c) => canUse && setColor(c)} />
          </div>

          {/* Verantwortliche — Personen-Auswahl im Kachel-Look */}
          <div className="field">
            <label className="label">Verantwortliche{assigneeIds.length ? ` · ${assigneeIds.length}` : ""}</label>
            <div className="person-grid">
              {options.users.map((u) => {
                const active = assigneeIds.includes(u.id);
                return (
                  <button
                    key={u.id}
                    type="button"
                    className="person-option"
                    data-active={active}
                    onClick={() => canUse && setAssigneeIds((a) => toggle(a, u.id))}
                  >
                    <Avatar name={u.name} src={u.avatarUrl} size={30} />
                    <span className="min-w-0 flex-1 truncate text-left font-bold">{u.name}</span>
                    <span className="select-check" data-active={active}>
                      {active ? <Icon name="check" size={13} /> : null}
                    </span>
                  </button>
                );
              })}
            </div>
          </div>

          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <div className="field">
              <label className="label">Deadline</label>
              <DatePicker value={deadline} onChange={setDeadline} disabled={!canUse} />
            </div>
            <div className="field">
              <label className="label">Projekt</label>
              <select className="select" value={projectId} onChange={(e) => setProjectId(e.target.value)} disabled={!canUse}>
                <option value="">— Kein Projekt —</option>
                {options.projects.map((p) => (
                  <option key={p.id} value={p.id}>{p.name}</option>
                ))}
              </select>
            </div>
          </div>

          {/* Labels — zuweisen (Erstellen/Löschen in den Board-Einstellungen) */}
          <div className="field">
            <label className="label">Labels{labelIds.length ? ` · ${labelIds.length}` : ""}</label>
            {labels.length === 0 ? (
              <p className="text-muted text-sm">
                Noch keine Labels{canManageBoard ? " — lege welche in den Board-Einstellungen an." : "."}
              </p>
            ) : (
              <div className="label-pick">
                {labels.map((l) => {
                  const on = labelIds.includes(l.id);
                  return (
                    <button
                      key={l.id}
                      type="button"
                      className="label-select"
                      data-active={on}
                      style={{ ["--lc" as string]: l.color }}
                      onClick={() => canUse && setLabelIds((a) => toggle(a, l.id))}
                    >
                      <span className="label-dot" style={{ background: l.color }} />
                      <span className="truncate">{l.name}</span>
                      {on ? <Icon name="check" size={13} /> : null}
                    </button>
                  );
                })}
              </div>
            )}
          </div>
        </div>

        {canUse ? (
          <div className="form-footer">
            {mode === "edit" ? (
              <button className="btn btn-ghost" onClick={remove} disabled={saving}>
                <Icon name="trash" size={15} /> Löschen
              </button>
            ) : (
              <span />
            )}
            <div className="flex items-center gap-2">
              <button className="btn btn-ghost" onClick={onClose} disabled={saving}>
                Abbrechen
              </button>
              <button className="btn btn-primary" onClick={save} disabled={saving || !title.trim()}>
                {saving ? "Speichern …" : mode === "create" ? "Erstellen" : "Speichern"}
              </button>
            </div>
          </div>
        ) : null}

        {mode === "edit" ? (
          <div className="mt-6 border-t pt-5" style={{ borderColor: "var(--line)" }}>
            <h3 className="mb-4">Kommentare</h3>
            <div className="flex flex-col gap-3">
              {comments.length === 0 ? (
                <p className="text-muted text-sm">Noch keine Kommentare.</p>
              ) : (
                comments.map((c) => {
                  const canDelete = c.authorId === currentUserId || canManageBoard;
                  return (
                    <div key={c.id} className="comment-row">
                      <Avatar name={c.authorName} src={c.authorAvatar} size={32} />
                      <div className="comment-body">
                        <div className="mb-0.5 flex items-center gap-2">
                          <span className="text-sm font-bold">{c.authorName}</span>
                          <span className="text-muted text-xs">{fmtTime(c.createdAt)}</span>
                        </div>
                        <div className="text-sm" style={{ wordBreak: "break-word" }}>{c.body}</div>
                      </div>
                      {canDelete ? (
                        <button className="comment-del" onClick={() => removeComment(c)} aria-label="Kommentar löschen">
                          <Icon name="trash" size={13} />
                        </button>
                      ) : null}
                    </div>
                  );
                })
              )}
            </div>
            {canComment ? (
              <div className="mt-4 flex items-end gap-2">
                <textarea
                  className="textarea"
                  style={{ minHeight: 44 }}
                  value={commentText}
                  onChange={(e) => setCommentText(e.target.value)}
                  placeholder="Kommentar schreiben …"
                />
                <button className="btn btn-primary" onClick={submitComment} disabled={!commentText.trim()}>
                  <Icon name="send" size={15} />
                </button>
              </div>
            ) : null}
          </div>
        ) : null}
      </div>
    </div>
  );
}
