import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { createAgent, getAgent, improveAgentPrompt, updateAgent } from "../../lib/api";
import { getErrorMessage } from "../../lib/errors";
import type { AgentRole, AgentTool } from "../../lib/types";
import {
  buttonClass,
  inputClass,
  labelClass,
  noticeClass,
  pageTitleClass,
  textAreaClass,
} from "../ui/primitives";

export default function AgentForm() {
  const navigate = useNavigate();
  const { agentId } = useParams<{ agentId: string }>();
  const isEditing = Boolean(agentId);

  const [name, setName] = useState("");
  const [role, setRole] = useState<AgentRole>("analyst");
  const [tool, setTool] = useState<AgentTool>("codex");
  const [customPrompt, setCustomPrompt] = useState("");
  const [isDefaultAgent, setIsDefaultAgent] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [initializing, setInitializing] = useState(false);
  const [improvingPrompt, setImprovingPrompt] = useState(false);

  useEffect(() => {
    async function loadAgent() {
      if (!agentId) return;
      setInitializing(true);
      setError(null);
      try {
        const agent = await getAgent(agentId);
        setName(agent.name);
        setRole(agent.role);
        setTool(agent.tool);
        setCustomPrompt(agent.custom_prompt);
        setIsDefaultAgent(agent.is_default);
      } catch (err: unknown) {
        setError(getErrorMessage(err));
      } finally {
        setInitializing(false);
      }
    }

    void loadAgent();
  }, [agentId]);

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault();
    setLoading(true);
    setError(null);

    try {
      if (isEditing && agentId) {
        await updateAgent(agentId, name, role, tool, customPrompt);
      } else {
        await createAgent(name, role, tool, customPrompt);
      }
      navigate("/agents");
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }

  async function handleImprovePrompt() {
    setImprovingPrompt(true);
    setError(null);

    try {
      const improvedPrompt = await improveAgentPrompt(name, role, tool, customPrompt);
      setCustomPrompt(improvedPrompt);
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setImprovingPrompt(false);
    }
  }

  return (
    <div className="mx-auto max-w-2xl p-8">
      <h2 className={`mb-6 ${pageTitleClass}`}>{isEditing ? "Edit agent" : "New agent"}</h2>

      <form onSubmit={handleSubmit} className="space-y-4">
        {initializing && <div className="text-sm text-gray-500">Loading agent...</div>}
        {isEditing && isDefaultAgent && (
          <div className={noticeClass("info")}>
            This is a default agent. Its tool and script/prompt can be modified, but its name and
            role are fixed.
          </div>
        )}

        <div>
          <label className={labelClass}>Name</label>
          <input
            type="text"
            value={name}
            onChange={(e) => setName(e.target.value)}
            disabled={isEditing && isDefaultAgent}
            required
            className={inputClass}
          />
        </div>

        <div>
          <label className={labelClass}>Role</label>
          <select
            value={role}
            onChange={(e) => setRole(e.target.value as AgentRole)}
            disabled={isEditing && isDefaultAgent}
            className={inputClass}
          >
            <option value="analyst">Analyst</option>
            <option value="developer">Developer</option>
          </select>
        </div>

        <div>
          <label className={labelClass}>Tool</label>
          <select
            value={tool}
            onChange={(e) => setTool(e.target.value as AgentTool)}
            className={inputClass}
          >
            <option value="codex">Codex</option>
            <option value="claude_code">Claude Code</option>
          </select>
        </div>

        <div>
          <div className="mb-1 flex items-center justify-between gap-3">
            <label className={labelClass}>
              Script / custom prompt (appended to built-in prompt)
            </label>
            <button
              type="button"
              onClick={() => void handleImprovePrompt()}
              disabled={loading || initializing || improvingPrompt}
              className={buttonClass({ variant: "success", size: "xs" })}
            >
              {improvingPrompt ? "Amélioration..." : "Amélioration"}
            </button>
          </div>
          <textarea
            rows={12}
            value={customPrompt}
            onChange={(e) => setCustomPrompt(e.target.value)}
            disabled={loading || initializing || improvingPrompt}
            className={`${textAreaClass} disabled:bg-gray-50`}
            placeholder="Extra instructions for this agent..."
          />
          <p className="mt-1 text-xs text-gray-500">
            Réécrit le prompt avec l&apos;outil sélectionné pour le rendre plus clair pour un LLM.
          </p>
        </div>

        {error && (
          <div className={noticeClass("error", true)}>
            {error}
          </div>
        )}

        <div className="flex gap-2">
          <button
            type="submit"
            disabled={loading || initializing || improvingPrompt}
            className={buttonClass({ variant: "primary" })}
          >
            {loading ? "Saving..." : isEditing ? "Save" : "Create"}
          </button>
          <button
            type="button"
            onClick={() => navigate(-1)}
            className={buttonClass({ variant: "secondary" })}
          >
            Cancel
          </button>
        </div>
      </form>
    </div>
  );
}
