"use client";

import { useCallback, useMemo, useState } from "react";
import { extractSuggestedTasks } from "@/lib/extraction-client";
import { StateNotice } from "@/components/StateNotice";
import { Button, Card } from "@/components/ui/Primitives";
import { createNoteTask } from "@/lib/notes-client";
import { toast } from "@/lib/toast";
import { getEmptyState, toUserFacingState, type UserFacingState } from "@/lib/user-facing-states";
import type { NoteTask } from "@/lib/types";

export function ExtractedTasksPanel({
  noteId,
  workspaceId,
  noteBody,
  persistedTasks,
  onTaskAccepted,
}: {
  noteId: string;
  workspaceId: string;
  noteBody: string;
  persistedTasks: NoteTask[];
  onTaskAccepted: () => void;
}) {
  const [proposals, setProposals] = useState<NoteTask[]>([]);
  const [scanning, setScanning] = useState(false);
  const [acceptingId, setAcceptingId] = useState<string | null>(null);
  const [noticeState, setNoticeState] = useState<UserFacingState | null>(null);

  const persistedTitles = useMemo(
    () => new Set(persistedTasks.map((t) => t.title.trim().toLowerCase())),
    [persistedTasks],
  );

  const handleScan = useCallback(async () => {
    setScanning(true);
    setNoticeState(null);
    try {
      const extracted = await extractSuggestedTasks(noteBody);
      const filtered = extracted.filter((t) => !persistedTitles.has(t.title.trim().toLowerCase()));
      setProposals(filtered);
      if (filtered.length === 0) {
        setNoticeState(getEmptyState("extraction", "suggested tasks"));
      }
    } catch (e) {
      const state = toUserFacingState(e, "extraction");
      setNoticeState(state);
      toast.error(state.message);
    } finally {
      setScanning(false);
    }
  }, [noteBody, persistedTitles]);

  const handleAccept = useCallback(
    async (task: NoteTask) => {
      setAcceptingId(task.id);
      try {
        await createNoteTask({
          id: crypto.randomUUID(),
          workspaceId,
          noteId,
          title: task.title,
          source: "extracted",
        });
        setProposals((p) => p.filter((x) => x.id !== task.id));
        toast.success("Task added");
        onTaskAccepted();
      } catch (e) {
        const state = toUserFacingState(e, "backend");
        setNoticeState(state);
        toast.error(state.message);
      } finally {
        setAcceptingId(null);
      }
    },
    [noteId, workspaceId, onTaskAccepted],
  );

  const handleDismiss = useCallback((taskId: string) => {
    setProposals((p) => p.filter((x) => x.id !== taskId));
  }, []);

  return (
    <Card style={{ padding: "var(--nl-space-5)", display: "grid", gap: "var(--nl-space-3)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", gap: "var(--nl-space-3)", alignItems: "center", flexWrap: "wrap" }}>
        <div style={{ fontWeight: 700 }}>Suggested tasks (AI)</div>
        <Button
          type="button"
          variant="secondary"
          disabled={scanning}
          loading={scanning}
          onClick={() => void handleScan()}
        >
          Scan note for tasks
        </Button>
      </div>
      <p style={{ margin: 0, color: "var(--nl-text-secondary)", fontSize: "var(--nl-fs-sm)" }}>
        Runs extraction on demand. Accept adds a backend task; dismiss only hides the suggestion for this session.
      </p>
      {noticeState ? (
        <StateNotice
          state={noticeState}
          compact
          onAction={noticeState.actionLabel ? () => void handleScan() : undefined}
        />
      ) : null}
      {proposals.length === 0 ? null : (
        <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "grid", gap: "var(--nl-space-2)" }}>
          {proposals.map((task) => (
            <li key={task.id} className="flex flex-wrap items-center justify-between gap-2 rounded-[var(--nl-radius-sm)] bg-[color:var(--nl-surface-muted)] p-3">
              <span>{task.title}</span>
              <span style={{ display: "flex", gap: 8 }}>
                <Button
                  type="button"
                  size="sm"
                  disabled={acceptingId === task.id}
                  loading={acceptingId === task.id}
                  onClick={() => void handleAccept(task)}
                >
                  Accept
                </Button>
                <Button
                  type="button"
                  variant="secondary"
                  size="sm"
                  onClick={() => handleDismiss(task.id)}
                >
                  Dismiss
                </Button>
              </span>
            </li>
          ))}
        </ul>
      )}
    </Card>
  );
}
