import { listen } from "@tauri-apps/api/event";
import { FormEvent, useEffect, useMemo, useState } from "react";
import { Link, useParams } from "react-router-dom";
import {
  cancelAgentTask,
  createAgentTask,
  listAgentTasks,
  listAgents,
  listProjectModules,
  retryAgentTask,
} from "../../lib/api";
import { getErrorMessage } from "../../lib/errors";
import type { Agent, AgentTask } from "../../lib/types";

interface TaskEventPayload {
  project_id: string;
  task_id: string;
  status: string;
  error?: string | null;
}

export default function ProjectTasks() {
  const { projectId } = useParams<{ projectId: string }>();

  const [agents, setAgents] = useState<Agent[]>([]);
  const [tasks, setTasks] = useState<AgentTask[]>([]);
  const [agentId, setAgentId] = useState("");
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [moduleEnabled, setModuleEnabled] = useState(true);
  const [creating, setCreating] = useState(false);
  const [workingTaskId, setWorkingTaskId] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const usableAgents = useMemo(
    () => agents.filter((agent) => agent.role === "analyst" || agent.role === "developer"),
    [agents]
  );

  async function refresh() {
    if (!projectId) return;

    setError(null);
    try {
      const [availableAgents, projectTasks, modules] = await Promise.all([
        listAgents(),
        listAgentTasks(projectId),
        listProjectModules(projectId),
      ]);
      setAgents(availableAgents);
      setTasks(projectTasks);
      setModuleEnabled(
        modules.find((mod) => mod.module_key === "agent_task_runner")?.enabled ?? true
      );
      if (!agentId && availableAgents.length > 0) {
        setAgentId(availableAgents[0].id);
      }
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    }
  }

  useEffect(() => {
    void refresh();
  }, [projectId]);

  useEffect(() => {
    if (!projectId) return;
    let stop: (() => void) | null = null;

    void (async () => {
      const unlisten = await listen<TaskEventPayload>("agent-task-updated", (event) => {
        if (event.payload.project_id !== projectId) return;
        void refresh();
      });
      stop = unlisten;
    })();

    return () => {
      if (stop) stop();
    };
  }, [projectId]);

  function statusBadgeClass(status: AgentTask["status"]): string {
    switch (status) {
      case "pending":
        return "bg-yellow-100 text-yellow-800";
      case "running":
        return "bg-blue-100 text-blue-800";
      case "done":
        return "bg-green-100 text-green-800";
      case "error":
        return "bg-red-100 text-red-800";
      case "cancelled":
        return "bg-gray-100 text-gray-700";
      default:
        return "bg-gray-100 text-gray-700";
    }
  }

  async function handleCreateTask(event: FormEvent) {
    event.preventDefault();
    if (!projectId || !agentId || !title.trim()) return;
    if (!moduleEnabled) {
      setError("Le module Agent task runner est désactivé pour ce projet.");
      return;
    }

    setCreating(true);
    setError(null);
    try {
      await createAgentTask(projectId, agentId, title.trim(), description.trim());
      setTitle("");
      setDescription("");
      await refresh();
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setCreating(false);
    }
  }

  async function handleRetry(taskId: string) {
    if (!moduleEnabled) {
      setError("Le module Agent task runner est désactivé pour ce projet.");
      return;
    }

    setWorkingTaskId(taskId);
    setError(null);
    try {
      await retryAgentTask(taskId);
      await refresh();
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setWorkingTaskId(null);
    }
  }

  async function handleCancel(taskId: string) {
    setWorkingTaskId(taskId);
    setError(null);
    try {
      await cancelAgentTask(taskId);
      await refresh();
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setWorkingTaskId(null);
    }
  }

  return (
    <div className="space-y-6 p-8">
      <div className="flex items-center justify-between gap-3">
        <h2 className="text-xl font-bold">Tâches agent</h2>
        {projectId && (
          <Link
            to={`/projects/${projectId}`}
            className="rounded bg-gray-200 px-4 py-2 text-sm text-gray-700 hover:bg-gray-300"
          >
            Retour
          </Link>
        )}
      </div>

      {error && (
        <div className="rounded border border-red-200 bg-red-50 p-2 text-sm text-red-600">
          {error}
        </div>
      )}
      {!moduleEnabled && (
        <div className="rounded border border-amber-200 bg-amber-50 p-2 text-sm text-amber-700">
          Le module est désactivé. Les tâches existantes restent visibles, mais la création et la relance sont bloquées.
        </div>
      )}

      <form onSubmit={handleCreateTask} className="rounded-lg border border-gray-200 bg-white p-4">
        <h3 className="mb-3 text-sm font-semibold text-gray-800">Créer une tâche</h3>
        <div className="grid gap-3 md:grid-cols-3">
          <select
            value={agentId}
            onChange={(e) => setAgentId(e.target.value)}
            className="rounded border border-gray-300 px-3 py-2 text-sm"
          >
            {usableAgents.map((agent) => (
              <option key={agent.id} value={agent.id}>
                {agent.name} ({agent.tool})
              </option>
            ))}
          </select>

          <input
            type="text"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Titre de la tâche"
            className="rounded border border-gray-300 px-3 py-2 text-sm"
          />

          <button
            type="submit"
            disabled={creating || !agentId || !title.trim() || !moduleEnabled}
            className="rounded bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
          >
            {creating ? "Création..." : "Créer"}
          </button>
        </div>

        <textarea
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          rows={4}
          placeholder="Description détaillée"
          className="mt-3 w-full rounded border border-gray-300 px-3 py-2 text-sm"
        />
      </form>

      <div className="space-y-3">
        {tasks.map((task) => (
          <div key={task.id} className="rounded-lg border border-gray-200 bg-white p-4">
            <div className="flex items-center justify-between gap-3">
              <div className="min-w-0">
                <div className="truncate text-sm font-semibold text-gray-900">{task.title}</div>
                <div className="mt-1 text-xs text-gray-500">
                  Créée le {new Date(task.created_at).toLocaleString()}
                </div>
              </div>
              <span className={`rounded-full px-2 py-0.5 text-xs font-medium ${statusBadgeClass(task.status)}`}>
                {task.status}
              </span>
            </div>

            {task.description && (
              <div className="mt-3 whitespace-pre-wrap text-sm text-gray-700">{task.description}</div>
            )}

            {task.result && (
              <div className="mt-3 rounded border border-green-200 bg-green-50 p-3 text-sm text-green-900 whitespace-pre-wrap">
                {task.result}
              </div>
            )}

            {task.error && (
              <div className="mt-3 rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700 whitespace-pre-wrap">
                {task.error}
              </div>
            )}

            <div className="mt-3 flex gap-2">
              {(task.status === "error" || task.status === "cancelled" || task.status === "done") && (
                <button
                  type="button"
                  onClick={() => void handleRetry(task.id)}
                  disabled={workingTaskId === task.id || !moduleEnabled}
                  className="rounded bg-gray-900 px-3 py-1 text-xs text-white hover:bg-black disabled:opacity-50"
                >
                  Relancer
                </button>
              )}

              {task.status === "pending" || task.status === "running" ? (
                <button
                  type="button"
                  onClick={() => void handleCancel(task.id)}
                  disabled={workingTaskId === task.id}
                  className="rounded bg-red-100 px-3 py-1 text-xs text-red-700 hover:bg-red-200 disabled:opacity-50"
                >
                  Annuler
                </button>
              ) : null}
            </div>
          </div>
        ))}

        {tasks.length === 0 && (
          <div className="text-sm text-gray-400">Aucune tâche pour ce projet.</div>
        )}
      </div>
    </div>
  );
}
