"use client";

import { useState } from "react";

import {
  AlertCircle,
  CheckCircle2,
  FlaskConical,
  GitBranch,
  Loader2,
  Lock,
  Unlock,
  User,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  testForgejoConnection,
  type ForgejoConnectionCreate,
  type ForgejoConnectionTestResult,
} from "@/lib/api-forgejo";

interface ForgejoConnectionFormProps {
  defaultValues?: Partial<ForgejoConnectionFormValues>;
  onSubmit: (values: ForgejoConnectionCreate) => Promise<void>;
  isSubmitting?: boolean;
  isTokenRequired?: boolean;
  existingTokenLastEight?: string | null;
  title?: string;
  description?: string;
  submitLabel?: string;
}

export interface ForgejoConnectionFormValues {
  name: string;
  base_url: string;
  token: string;
}

export function ForgejoConnectionForm({
  defaultValues = {},
  onSubmit,
  isSubmitting = false,
  isTokenRequired = true,
  existingTokenLastEight,
  title = "Git Project Connection",
  description = "Connect a Git provider so Pipeline can track issues.",
  submitLabel = "Save Connection",
}: ForgejoConnectionFormProps) {
  const [error, setError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);
  const [isTesting, setIsTesting] = useState(false);
  const [testResult, setTestResult] = useState<ForgejoConnectionTestResult | null>(null);
  const [name, setName] = useState(defaultValues.name || "");
  const [baseUrl, setBaseUrl] = useState(defaultValues.base_url || "");
  const [token, setToken] = useState(defaultValues.token || "");
  const isBusy = isSubmitting || isSaving;

  const tokenHelpText = isTokenRequired
    ? "Paste your Forgejo personal access token. Use read:issue scope; add write:issue if Pipeline should close issues."
    : existingTokenLastEight
      ? `Leave blank to keep the saved token ending in ${existingTokenLastEight}. Paste a new token to replace it.`
      : "Paste a new personal access token to replace the saved one.";

  const canTest = baseUrl.trim().length > 0 && token.trim().length > 0;

  async function handleTest() {
    setTestResult(null);
    setError(null);
    setIsTesting(true);
    try {
      const result = await testForgejoConnection({
        base_url: baseUrl.trim(),
        token: token.trim(),
      });
      setTestResult(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Test request failed.");
    } finally {
      setIsTesting(false);
    }
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    try {
      setIsSaving(true);
      await onSubmit({ name, base_url: baseUrl, token });
    } catch (err) {
      const msg = err instanceof Error ? err.message : "An error occurred";
      setError(msg);
    } finally {
      setIsSaving(false);
    }
  }

  return (
    <div className="w-full max-w-2xl space-y-4">
      <form
        onSubmit={handleSubmit}
        className="surface-panel space-y-6 rounded-2xl p-4 sm:p-6"
      >
        <div className="space-y-4">
          <div>
            <h3 className="text-lg font-semibold text-strong">{title}</h3>
            {description && (
              <p className="mt-1 text-sm text-muted">{description}</p>
            )}
          </div>

          {error && (
            <div className="rounded-xl border border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)] p-4 text-[color:var(--danger)]">
              <p className="font-medium">
                {error === "Failed to fetch"
                  ? "Could not reach Pipeline backend"
                  : "Error"}
              </p>
              <p className="text-sm">
                {error === "Failed to fetch"
                  ? "Pipeline could not connect to its own API. Check that NEXT_PUBLIC_API_URL points to your backend and that your frontend origin is listed in CORS_ORIGINS."
                  : error}
              </p>
            </div>
          )}

          <div className="space-y-2">
            <label htmlFor="name" className="text-sm font-medium">
              Name
            </label>
            <Input
              id="name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Team Git"
              disabled={isBusy}
              required
            />
            <p className="text-xs text-muted">
              A memorable name for this Git Projects connection.
            </p>
          </div>

          <div className="space-y-2">
            <label htmlFor="base_url" className="text-sm font-medium">
              Base URL
            </label>
            <Input
              id="base_url"
              value={baseUrl}
              onChange={(e) => {
                setBaseUrl(e.target.value.trimEnd().replace(/\/+$/, ""));
                setTestResult(null);
              }}
              placeholder="https://git.example.com"
              disabled={isBusy}
              required
            />
            <p className="text-xs text-muted">
              The base URL of your Forgejo instance, without a trailing slash.
            </p>
          </div>

          <div className="space-y-2">
            <label htmlFor="token" className="text-sm font-medium">
              Token
            </label>
            <Input
              id="token"
              type="password"
              value={token}
              onChange={(e) => {
                setToken(e.target.value);
                setTestResult(null);
              }}
              placeholder={
                isTokenRequired
                  ? "Paste token"
                  : existingTokenLastEight
                    ? `Current token ends in ${existingTokenLastEight}`
                    : "Paste token"
              }
              disabled={isBusy}
              required={isTokenRequired}
              autoComplete="new-password"
            />
            <p className="text-xs text-muted">{tokenHelpText}</p>
          </div>
        </div>

        <div className="flex flex-col-reverse gap-3 border-t border-[color:var(--border)] pt-4 sm:flex-row sm:justify-end">
          <Button
            type="button"
            variant="outline"
            onClick={() => window.history.back()}
            disabled={isBusy}
          >
            Cancel
          </Button>
          <Button
            type="button"
            variant="outline"
            onClick={handleTest}
            disabled={isBusy || isTesting || !canTest}
          >
            {isTesting ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin" />
                Testing…
              </>
            ) : (
              <>
                <FlaskConical className="h-4 w-4" />
                Test Connection
              </>
            )}
          </Button>
          <Button type="submit" disabled={isBusy}>
            {isBusy ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                Saving…
              </>
            ) : (
              submitLabel
            )}
          </Button>
        </div>
      </form>

      {/* Test results panel */}
      {testResult && (
        <div
          className={`rounded-2xl border p-4 sm:p-6 ${
            testResult.valid
              ? "border-[color:rgba(52,211,153,0.35)] bg-[color:rgba(52,211,153,0.06)]"
              : "border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.06)]"
          }`}
        >
          {/* Header */}
          <div className="flex items-start gap-3 mb-4">
            {testResult.valid ? (
              <CheckCircle2 className="h-5 w-5 shrink-0 text-[color:var(--success)] mt-0.5" />
            ) : (
              <AlertCircle className="h-5 w-5 shrink-0 text-[color:var(--danger)] mt-0.5" />
            )}
            <div className="min-w-0">
              <p className={`font-semibold ${testResult.valid ? "text-[color:var(--success)]" : "text-[color:var(--danger)]"}`}>
                {testResult.valid ? "Connection successful" : "Connection failed"}
              </p>
              <p className="text-xs text-muted mt-0.5">
                {Math.round(testResult.response_time_ms)}ms
              </p>
            </div>
          </div>

          {testResult.error && (
            <p className="text-sm text-[color:var(--danger)] mb-4">{testResult.error}</p>
          )}

          {testResult.valid && (
            <div className="space-y-4">
              {/* Identity */}
              <div className="flex items-center gap-2 text-sm text-strong">
                <User className="h-4 w-4 shrink-0 text-muted" />
                <span>
                  Connected as{" "}
                  <strong>@{testResult.user_login}</strong>
                  {testResult.user_full_name && testResult.user_full_name !== testResult.user_login
                    ? ` (${testResult.user_full_name})`
                    : ""}
                </span>
              </div>

              {/* Repo list */}
              <div>
                <div className="flex items-center gap-2 text-sm font-medium text-strong mb-2">
                  <GitBranch className="h-4 w-4 shrink-0 text-muted" />
                  <span>
                    {testResult.repo_count}{" "}
                    {testResult.repo_count === 1 ? "repository" : "repositories"} accessible
                  </span>
                </div>
                {testResult.repos.length > 0 && (
                  <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] divide-y divide-[color:var(--border)] overflow-hidden">
                    {testResult.repos.map((repo) => (
                      <div
                        key={repo.full_name}
                        className="flex items-start gap-3 px-4 py-2.5"
                      >
                        {repo.private ? (
                          <Lock className="h-3.5 w-3.5 shrink-0 text-muted mt-0.5" />
                        ) : (
                          <Unlock className="h-3.5 w-3.5 shrink-0 text-muted mt-0.5" />
                        )}
                        <div className="min-w-0">
                          <p className="text-sm font-medium text-strong truncate">
                            {repo.full_name}
                          </p>
                          {repo.description && (
                            <p className="text-xs text-muted truncate">{repo.description}</p>
                          )}
                        </div>
                        <span className="ml-auto shrink-0 font-mono text-xs text-muted">
                          {repo.default_branch}
                        </span>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
