import { useState, useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import {
  listProjects,
  getTuleapCredentials,
  setTuleapCredentials,
  deleteTuleapCredentials,
  testTuleapConnection,
} from "../../lib/api";
import { getErrorMessage } from "../../lib/errors";
import type { Project, TuleapCredentialsSafe } from "../../lib/types";
import ConfirmModal from "../ui/ConfirmModal";

function normalizeScope(value: string): string | null {
  return value === "" ? null : value;
}

export default function SettingsPage() {
  const [searchParams] = useSearchParams();
  const initialProjectId = searchParams.get("projectId");

  const [projects, setProjects] = useState<Project[]>([]);
  const [selectedProjectId, setSelectedProjectId] = useState<string | null>(initialProjectId);

  const [tuleapUrl, setTuleapUrl] = useState("");
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [existing, setExisting] = useState<TuleapCredentialsSafe | null>(null);

  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [loadingScope, setLoadingScope] = useState(false);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);

  const selectedProject =
    selectedProjectId === null
      ? null
      : projects.find((project) => project.id === selectedProjectId) ?? null;

  const hasScopedCredentials =
    existing !== null && (existing.project_id ?? null) === selectedProjectId;

  const usingGlobalFallback =
    selectedProjectId !== null && existing !== null && existing.project_id !== selectedProjectId;

  useEffect(() => {
    listProjects()
      .then((items) => {
        setProjects(items);
        if (initialProjectId && !items.some((project) => project.id === initialProjectId)) {
          setSelectedProjectId(null);
        }
      })
      .catch((err: unknown) => {
        setError(getErrorMessage(err));
      });
  }, [initialProjectId]);

  useEffect(() => {
    let cancelled = false;

    setLoadingScope(true);
    setError(null);
    setSuccess(null);

    getTuleapCredentials(selectedProjectId)
      .then((creds) => {
        if (cancelled) return;

        setExisting(creds);
        if (creds) {
          setTuleapUrl(creds.tuleap_url);
          setUsername(creds.username);
        } else {
          setTuleapUrl("");
          setUsername("");
        }
        setPassword("");
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setExisting(null);
        setTuleapUrl("");
        setUsername("");
        setPassword("");
        setError(getErrorMessage(err));
      })
      .finally(() => {
        if (!cancelled) {
          setLoadingScope(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [selectedProjectId]);

  function clearMessages() {
    setError(null);
    setSuccess(null);
  }

  async function handleSave(e: React.FormEvent) {
    e.preventDefault();
    clearMessages();
    setSaving(true);
    try {
      const creds = await setTuleapCredentials(selectedProjectId, tuleapUrl, username, password);
      setExisting(creds);
      setPassword("");
      setSuccess(selectedProjectId ? "Project credentials saved." : "Global credentials saved.");
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setSaving(false);
    }
  }

  async function handleTest() {
    clearMessages();
    setTesting(true);
    try {
      const msg = await testTuleapConnection(selectedProjectId);
      setSuccess(msg);
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setTesting(false);
    }
  }

  async function handleDelete() {
    setIsDeleteModalOpen(false);
    clearMessages();
    setDeleting(true);
    try {
      await deleteTuleapCredentials(selectedProjectId);

      const refreshed = await getTuleapCredentials(selectedProjectId);
      setExisting(refreshed);
      setTuleapUrl(refreshed?.tuleap_url ?? "");
      setUsername(refreshed?.username ?? "");
      setPassword("");

      if (selectedProjectId && refreshed && refreshed.project_id === null) {
        setSuccess("Project credentials deleted. Global fallback credentials are now used.");
      } else {
        setSuccess("Credentials deleted.");
      }
    } catch (err: unknown) {
      setError(getErrorMessage(err));
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="max-w-lg mx-auto p-8">
      <h2 className="text-xl font-bold mb-6">Settings</h2>

      <div className="bg-white rounded-lg border border-gray-200 p-6">
        <h3 className="text-base font-semibold mb-4">Tuleap credentials</h3>

        <div className="mb-4">
          <label className="block text-sm font-medium text-gray-700 mb-1">Scope</label>
          <select
            value={selectedProjectId ?? ""}
            onChange={(e) => setSelectedProjectId(normalizeScope(e.target.value))}
            className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
          >
            <option value="">Global fallback</option>
            {projects.map((project) => (
              <option key={project.id} value={project.id}>
                {project.name}
              </option>
            ))}
          </select>
          <p className="mt-2 text-xs text-gray-500">
            {selectedProject
              ? `Les trackers du projet \"${selectedProject.name}\" utilisent d'abord ce scope, puis le fallback global.`
              : "Credentials par défaut pour tous les projets sans credentials dédiés."}
          </p>
        </div>

        {loadingScope ? (
          <div className="text-sm text-gray-500 mb-4">Loading credentials...</div>
        ) : null}

        {usingGlobalFallback && (
          <div className="mb-4 rounded border border-amber-200 bg-amber-50 p-3 text-sm text-amber-700">
            Aucun credential spécifique au projet n'est configuré. Le fallback global est utilisé.
          </div>
        )}

        <form onSubmit={handleSave} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Tuleap URL</label>
            <input
              type="url"
              value={tuleapUrl}
              onChange={(e) => setTuleapUrl(e.target.value)}
              required
              placeholder="https://tuleap.example.com"
              className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Username</label>
            <input
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              required
              className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Password</label>
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
              className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {error && (
            <div className="text-red-600 text-sm bg-red-50 border border-red-200 rounded p-2">
              {error}
            </div>
          )}

          {success && (
            <div className="text-green-700 text-sm bg-green-50 border border-green-200 rounded p-2">
              {success}
            </div>
          )}

          <div className="flex gap-2 flex-wrap">
            <button
              type="submit"
              disabled={saving || loadingScope}
              className="px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50"
            >
              {saving ? "Saving..." : "Save"}
            </button>
            <button
              type="button"
              onClick={handleTest}
              disabled={testing || !existing || loadingScope}
              className="px-4 py-2 bg-gray-200 rounded text-sm hover:bg-gray-300 disabled:opacity-50"
            >
              {testing ? "Testing..." : "Test connection"}
            </button>
            {hasScopedCredentials && (
              <button
                type="button"
                onClick={() => setIsDeleteModalOpen(true)}
                disabled={deleting}
                className="px-4 py-2 bg-red-600 text-white rounded text-sm hover:bg-red-700 disabled:opacity-50"
              >
                {deleting ? "Deleting..." : "Delete"}
              </button>
            )}
          </div>
        </form>
      </div>

      <ConfirmModal
        isOpen={isDeleteModalOpen}
        confirmDisabled={deleting}
        onCancel={() => setIsDeleteModalOpen(false)}
        onConfirm={() => void handleDelete()}
      />
    </div>
  );
}
