import { useCallback, useEffect, useState } from "react";
import type { Project, ScheduledTask, SchedulerNotification } from "../../../lib/types";
import {
  clearSchedulerNotifications,
  getScheduledTaskLog,
  getSchedulerNotifications,
  listScheduledTasks,
  removeScheduledTask,
  runScheduledTaskNow,
  setScheduledTaskEnabled,
} from "../../../lib/tauri-commands";
import { useAppState } from "../../../store/appState";
import Button from "../../ui/Button";
import Toggle from "../../ui/Toggle";
import Modal from "../../ui/Modal";
import StatusIndicator from "../../ui/StatusIndicator";
import TaskEditorModal from "./TaskEditorModal";
import { formatAge, formatRunningFor } from "./format";

interface Props {
  project: Project;
}

/**
 * UI for `triple-c-scheduler`, which ships in every container and until now
 * had no interface beyond a CLAUDE.md paragraph.
 */
export default function AutomationTab({ project }: Props) {
  const [tasks, setTasks] = useState<ScheduledTask[]>([]);
  const [notifications, setNotifications] = useState<SchedulerNotification[]>([]);
  const [loading, setLoading] = useState(false);
  const [busyTaskId, setBusyTaskId] = useState<string | null>(null);
  const [log, setLog] = useState<{ task: ScheduledTask; text: string } | null>(null);
  const [confirmRemoveId, setConfirmRemoveId] = useState<string | null>(null);
  /** `undefined` = closed, `null` = creating, a task = editing it. */
  const [editing, setEditing] = useState<ScheduledTask | null | undefined>(undefined);
  const pushToast = useAppState((s) => s.pushToast);
  const running = project.status === "running";

  const load = useCallback(() => {
    if (!running) {
      setTasks([]);
      setNotifications([]);
      return;
    }
    setLoading(true);
    Promise.all([
      listScheduledTasks(project.id).catch(() => [] as ScheduledTask[]),
      getSchedulerNotifications(project.id).catch(
        () => [] as SchedulerNotification[],
      ),
    ])
      .then(([t, n]) => {
        setTasks(t);
        setNotifications(n);
      })
      .finally(() => setLoading(false));
  }, [project.id, running]);

  useEffect(load, [load]);

  // A task in flight is the one state this view cannot sit still for: runs are
  // detached, so without polling "Run now" looks like it did nothing until the
  // user reaches for Refresh. Polling stops as soon as nothing is running.
  //
  // `justTriggered` covers the gap between firing a run and the runner writing
  // its state file — a second or two in which the task still reads as idle, and
  // where giving up on polling would reproduce the exact silence this fixes.
  const anyTaskRunning = tasks.some((t) => t.running);
  const [justTriggered, setJustTriggered] = useState(0);
  useEffect(() => {
    if (!running) return;
    if (!anyTaskRunning && Date.now() - justTriggered > 20_000) return;
    const timer = setInterval(load, anyTaskRunning ? 5000 : 1500);
    return () => clearInterval(timer);
  }, [running, anyTaskRunning, justTriggered, load]);

  const withTask = async (taskId: string, label: string, fn: () => Promise<unknown>) => {
    setBusyTaskId(taskId);
    try {
      await fn();
      load();
    } catch (e) {
      pushToast({ kind: "error", message: `${label} failed`, detail: String(e) });
    } finally {
      setBusyTaskId(null);
    }
  };

  const openLog = async (task: ScheduledTask) => {
    setBusyTaskId(task.id);
    try {
      const text = await getScheduledTaskLog(project.id, task.id, 200);
      setLog({ task, text });
    } catch (e) {
      pushToast({
        kind: "error",
        message: `Could not read the log for “${task.name}”`,
        detail: String(e),
      });
    } finally {
      setBusyTaskId(null);
    }
  };

  const removing = tasks.find((t) => t.id === confirmRemoveId) ?? null;

  return (
    <div className="p-4 space-y-6 max-w-4xl">
      {/* Notifications */}
      {notifications.length > 0 && (
        <section className="border border-[var(--accent)]/40 bg-[var(--accent-muted)] rounded-[var(--radius-panel)]">
          <header className="flex items-center justify-between px-3 py-2 border-b border-[var(--border-color)]">
            <h2 className="text-[11px] font-semibold uppercase tracking-wide text-[var(--accent)]">
              {notifications.length} notification
              {notifications.length === 1 ? "" : "s"}
            </h2>
            <Button
              onClick={async () => {
                try {
                  await clearSchedulerNotifications(project.id);
                  setNotifications([]);
                } catch (e) {
                  pushToast({
                    kind: "error",
                    message: "Could not clear notifications",
                    detail: String(e),
                  });
                }
              }}
            >
              Clear all
            </Button>
          </header>
          <ul className="divide-y divide-[var(--border-color)]">
            {notifications.map((n, i) => (
              <li key={`${n.task_id}-${i}`} className="px-3 py-2">
                <div className="flex items-center gap-2 text-xs">
                  <span className="font-medium text-[var(--text-primary)]">
                    {n.task_name ?? n.task_id}
                  </span>
                  {n.status && (
                    <StatusIndicator
                      tone={n.status.toLowerCase() === "success" ? "ok" : "error"}
                      label={n.status}
                    />
                  )}
                  <span className="text-[var(--text-secondary)] ml-auto">
                    {formatAge(n.created_at) ?? n.time ?? ""}
                  </span>
                </div>
                <p className="mt-0.5 text-xs text-[var(--text-secondary)] whitespace-pre-wrap break-words">
                  {n.summary ?? n.body}
                </p>
              </li>
            ))}
          </ul>
        </section>
      )}

      <section>
        <div className="flex items-center justify-between mb-3">
          <p className="text-xs text-[var(--text-secondary)]">
            Recurring Claude Code runs managed by{" "}
            <code className="font-mono text-[var(--text-primary)]">
              triple-c-scheduler
            </code>{" "}
            inside the container.
          </p>
          <div className="flex items-center gap-2">
            <Button onClick={load} disabled={!running || loading}>
              {loading ? "Refreshing…" : "Refresh"}
            </Button>
            <Button variant="primary" disabled={!running} onClick={() => setEditing(null)}>
              New task
            </Button>
          </div>
        </div>

        {!running ? (
          <p className="text-[13px] text-[var(--text-secondary)]">
            Start the container to list its scheduled tasks.
          </p>
        ) : tasks.length === 0 && !loading ? (
          <p className="text-[13px] text-[var(--text-secondary)]">
            No scheduled tasks yet. Use <strong>New task</strong>, or ask Claude to add one with{" "}
            <code className="font-mono">triple-c-scheduler add</code>.
          </p>
        ) : (
          <ul className="space-y-1">
            {tasks.map((task) => (
              <li
                key={task.id}
                className="flex items-center gap-3 px-3 py-2 bg-[var(--bg-secondary)] border border-[var(--border-color)] rounded-[var(--radius-control)]"
              >
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2">
                    <span className="text-[13px] font-medium text-[var(--text-primary)] truncate">
                      {task.name}
                    </span>
                    <span className="text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded-[var(--radius-control)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)]">
                      {task.task_type}
                    </span>
                    {task.running && (
                      <StatusIndicator
                        tone="busy"
                        label={`Running ${formatRunningFor(task.running_since) ?? ""}`.trim()}
                      />
                    )}
                  </div>
                  <div className="text-xs text-[var(--text-secondary)] font-mono truncate">
                    {task.at ?? task.schedule}
                    {task.last_run ? ` · last run ${formatAge(task.last_run) ?? task.last_run}` : ""}
                  </div>
                </div>
                <Toggle
                  label={`${task.name} enabled`}
                  checked={task.enabled}
                  disabled={busyTaskId === task.id}
                  onChange={(v) =>
                    withTask(task.id, "Toggle task", () =>
                      setScheduledTaskEnabled(project.id, task.id, v),
                    )
                  }
                />
                <Button
                  disabled={busyTaskId === task.id || task.running}
                  onClick={() =>
                    withTask(task.id, "Run now", async () => {
                      await runScheduledTaskNow(project.id, task.id);
                      setJustTriggered(Date.now());
                    })
                  }
                >
                  {task.running ? "Running…" : "Run now"}
                </Button>
                <Button disabled={busyTaskId === task.id} onClick={() => setEditing(task)}>
                  Edit
                </Button>
                <Button disabled={busyTaskId === task.id} onClick={() => openLog(task)}>
                  Log
                </Button>
                <Button
                  variant="danger"
                  disabled={busyTaskId === task.id}
                  onClick={() => setConfirmRemoveId(task.id)}
                >
                  Remove
                </Button>
              </li>
            ))}
          </ul>
        )}
      </section>

      {editing !== undefined && (
        <TaskEditorModal
          project={project}
          task={editing}
          onClose={() => setEditing(undefined)}
          onSaved={load}
        />
      )}

      {log && (
        <Modal
          title={`Log — ${log.task.name}`}
          onClose={() => setLog(null)}
          widthClassName="w-[46rem]"
          footer={<Button onClick={() => setLog(null)}>Close</Button>}
        >
          <pre className="whitespace-pre-wrap break-words font-mono text-xs text-[var(--text-secondary)]">
            {log.text.trim() || "(empty log)"}
          </pre>
        </Modal>
      )}

      {removing && (
        <Modal
          title="Remove scheduled task"
          onClose={() => setConfirmRemoveId(null)}
          widthClassName="w-[26rem]"
          footer={
            <>
              <Button variant="ghost" onClick={() => setConfirmRemoveId(null)}>
                Cancel
              </Button>
              <Button
                className="bg-[var(--error-emphasis)] text-white border border-transparent hover:opacity-90"
                onClick={() => {
                  setConfirmRemoveId(null);
                  withTask(removing.id, "Remove task", () =>
                    removeScheduledTask(project.id, removing.id),
                  );
                }}
              >
                Remove
              </Button>
            </>
          }
        >
          <p className="text-[13px] text-[var(--text-secondary)]">
            Remove <strong className="text-[var(--text-primary)]">{removing.name}</strong>{" "}
            from this container&rsquo;s scheduler?
          </p>
        </Modal>
      )}
    </div>
  );
}
