import { useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useEffect } from "react";
import {
  addTracker,
  getTrackerFields,
  listAgents,
  listTrackers,
  updateTracker,
} from "../../lib/api";
import { getErrorMessage } from "../../lib/errors";
import type { FilterGroup, TrackerField, Agent } from "../../lib/types";
import FilterBuilder from "./FilterBuilder";
import {
  buttonClass,
  cardContentClass,
  inputClass,
  labelClass,
  noticeClass,
  pageTitleClass,
} from "../ui/primitives";

export default function TrackerConfig() {
  const { projectId, trackerConfigId } = useParams<{ projectId: string; trackerConfigId: string }>();
  const navigate = useNavigate();
  const isEditing = Boolean(trackerConfigId);

  const [trackerId, setTrackerId] = useState<number | "">("");
  const [trackerLabel, setTrackerLabel] = useState("");
  const [pollingInterval, setPollingInterval] = useState(10);
  const [fields, setFields] = useState<TrackerField[]>([]);
  const [fieldsLoaded, setFieldsLoaded] = useState(false);
  const [fieldsLoading, setFieldsLoading] = useState(false);
  const [filters, setFilters] = useState<FilterGroup[]>([]);
  const [agents, setAgents] = useState<Agent[]>([]);
  const [analystAgentId, setAnalystAgentId] = useState("");
  const [developerAgentId, setDeveloperAgentId] = useState("");
  const [enabled, setEnabled] = useState(true);
  const [trackerStatus, setTrackerStatus] = useState<"valid" | "invalid">("valid");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [initializing, setInitializing] = useState(false);

  function sortTrackerFields(input: TrackerField[]): TrackerField[] {
    return input
      .map((field) => ({
        ...field,
        values: [...field.values].sort((a, b) =>
          a.label.localeCompare(b.label, "fr", { sensitivity: "base" })
        ),
      }))
      .sort((a, b) =>
        a.label.localeCompare(b.label, "fr", { sensitivity: "base" })
      );
  }

  const analystAgents = agents.filter((agent) => agent.role === "analyst");
  const developerAgents = agents.filter((agent) => agent.role === "developer");

  useEffect(() => {
    async function loadAgents() {
      try {
        const all = await listAgents();
        setAgents(all);
      } catch (err: unknown) {
        setError(getErrorMessage(err));
      }
    }

    void loadAgents();
  }, []);

  useEffect(() => {
    if (isEditing) return;
    if (!analystAgentId && analystAgents.length > 0) {
      setAnalystAgentId(analystAgents[0].id);
    }
    if (!developerAgentId && developerAgents.length > 0) {
      setDeveloperAgentId(developerAgents[0].id);
    }
  }, [isEditing, analystAgentId, analystAgents, developerAgentId, developerAgents]);

  useEffect(() => {
    async function loadTrackerForEdit() {
      if (!projectId || !trackerConfigId) return;
      setInitializing(true);
      setError(null);
      try {
        const trackers = await listTrackers(projectId);
        const tracker = trackers.find((t) => t.id === trackerConfigId);
        if (!tracker) {
          setError("Tracker not found.");
          return;
        }
        setTrackerId(tracker.tracker_id);
        setTrackerLabel(tracker.tracker_label);
        setPollingInterval(tracker.polling_interval);
        setFilters(tracker.filters);
        setAnalystAgentId(tracker.analyst_agent_id ?? "");
        setDeveloperAgentId(tracker.developer_agent_id ?? "");
        setEnabled(tracker.enabled);
        setTrackerStatus(tracker.status === "invalid" ? "invalid" : "valid");

        const trackerFields = await getTrackerFields(projectId, tracker.tracker_id);
        setFields(sortTrackerFields(trackerFields));
        setFieldsLoaded(true);
      } catch (err: unknown) {
        setError(getErrorMessage(err));
      } finally {
        setInitializing(false);
      }
    }

    void loadTrackerForEdit();
  }, [projectId, trackerConfigId]);

  async function handleLoadFields() {
    if (!trackerId || !projectId) return;
    setFieldsLoading(true);
    setError(null);
    try {
      const result = await getTrackerFields(projectId, Number(trackerId));
      setFields(sortTrackerFields(result));
      setFieldsLoaded(true);
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setFieldsLoading(false);
    }
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!projectId || trackerId === "") return;
    if (!analystAgentId || !developerAgentId) {
      setError("Please select one analyst agent and one developer agent.");
      return;
    }

    setError(null);
    setLoading(true);

    try {
      if (isEditing && trackerConfigId) {
        await updateTracker(
          trackerConfigId,
          Number(trackerId),
          trackerLabel,
          pollingInterval,
          analystAgentId,
          developerAgentId,
          filters,
          enabled
        );
      } else {
        await addTracker(
          projectId,
          Number(trackerId),
          trackerLabel,
          pollingInterval,
          analystAgentId,
          developerAgentId,
          filters
        );
      }
      navigate(`/projects/${projectId}`);
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }

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

      <form onSubmit={handleSubmit} className="space-y-6">
        {initializing && (
          <div className="text-sm text-gray-500">Loading tracker...</div>
        )}

        {analystAgents.length === 0 || developerAgents.length === 0 ? (
          <div className={noticeClass("warning")}>
            You need at least one analyst agent and one developer agent before creating a tracker.
          </div>
        ) : null}

        {isEditing && trackerStatus === "invalid" && (
          <div className={noticeClass("error")}>
            This tracker is invalid. Select valid agents and save to reactivate it.
          </div>
        )}

        {/* Basic fields */}
        <div className={`${cardContentClass} space-y-4`}>
          <div>
            <label className={labelClass}>
              Tracker ID
            </label>
            <div className="flex gap-2">
              <input
                type="number"
                value={trackerId}
                onChange={(e) => {
                  setTrackerId(e.target.value === "" ? "" : Number(e.target.value));
                  setFieldsLoaded(false);
                  setFields([]);
                }}
                required
                min={1}
                className={`w-40 ${inputClass}`}
                placeholder="e.g. 42"
              />
              <button
                type="button"
                onClick={handleLoadFields}
                disabled={!trackerId || fieldsLoading}
                className={buttonClass({ variant: "primary" })}
              >
                {fieldsLoading ? "Loading..." : "Load tracker fields"}
              </button>
            </div>
          </div>

          <div>
            <label className={labelClass}>
              Label
            </label>
            <input
              type="text"
              value={trackerLabel}
              onChange={(e) => setTrackerLabel(e.target.value)}
              required
              placeholder="e.g. Bugs"
              className={inputClass}
            />
          </div>

          <div>
            <label className={labelClass}>
              Polling interval (minutes)
            </label>
            <input
              type="number"
              value={pollingInterval}
              onChange={(e) => setPollingInterval(Number(e.target.value))}
              required
              min={1}
              className={`w-40 ${inputClass}`}
            />
          </div>

          {isEditing && (
            <label className="flex items-center gap-2 text-sm text-gray-700">
              <input
                type="checkbox"
                checked={enabled}
                onChange={(e) => setEnabled(e.target.checked)}
              />
              Tracker enabled
            </label>
          )}
        </div>

        {/* Filter builder */}
        {fieldsLoaded && (
          <div>
            <h3 className="text-sm font-semibold text-gray-700 mb-2">Filters</h3>
            <FilterBuilder
              groups={filters}
              onChange={setFilters}
              availableFields={fields}
            />
          </div>
        )}

        {/* Agent config */}
        <div className={`${cardContentClass} space-y-4`}>
          <h3 className="text-sm font-semibold text-gray-700">Agent configuration</h3>
          <div>
            <label className={labelClass}>
              Analyst agent
            </label>
            <select
              value={analystAgentId}
              onChange={(e) => setAnalystAgentId(e.target.value)}
              required
              className={inputClass}
            >
              <option value="">Select an analyst agent</option>
              {analystAgents.map((agent) => (
                <option key={agent.id} value={agent.id}>
                  {agent.name} ({agent.tool === "codex" ? "Codex" : "Claude Code"})
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className={labelClass}>
              Developer agent
            </label>
            <select
              value={developerAgentId}
              onChange={(e) => setDeveloperAgentId(e.target.value)}
              required
              className={inputClass}
            >
              <option value="">Select a developer agent</option>
              {developerAgents.map((agent) => (
                <option key={agent.id} value={agent.id}>
                  {agent.name} ({agent.tool === "codex" ? "Codex" : "Claude Code"})
                </option>
              ))}
            </select>
          </div>
        </div>

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

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