"use client";

import { useState } from "react";
import { Copy, Eye, EyeOff, KeyRound, Loader2, Save, X } from "lucide-react";
import { Button, Input, Label } from "@/components/ui";

type Credentials = {
  username: string;
  password: string;
};

export function InstanceCredentials({ instance_id }: { instance_id: number | string }) {
  const id = typeof instance_id === "number" ? instance_id.toString() : instance_id;
  const [credentials, setCredentials] = useState<Credentials | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [visible, setVisible] = useState(false);
  const [copied, setCopied] = useState("");
  const [editing, setEditing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  async function loadCredentials() {
    if (credentials) {
      setVisible((value) => !value);
      return true;
    }

    setLoading(true);
    setError("");
    const response = await fetch(`/api/instances/${id}/credentials`);
    const body = (await response.json()) as { credentials?: Credentials; error?: string };
    setLoading(false);

    if (!response.ok || !body.credentials) {
      setError(body.error || "Could not load login details.");
      return false;
    }

    setCredentials(body.credentials);
    setUsername(body.credentials.username);
    setPassword(body.credentials.password);
    setVisible(true);
    return true;
  }

  async function startEditing() {
    if (!credentials) {
      const loaded = await loadCredentials();
      if (!loaded) return;
    }
    setError("");
    setEditing(true);
    setVisible(true);
  }

  async function saveCredentials() {
    setSaving(true);
    setError("");
    const response = await fetch(`/api/instances/${id}/credentials`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ username, password })
    });
    const body = (await response.json()) as { credentials?: Credentials; error?: string };
    setSaving(false);

    if (!response.ok || !body.credentials) {
      setError(body.error || "Could not update login details.");
      return;
    }

    setCredentials(body.credentials);
    setUsername(body.credentials.username);
    setPassword(body.credentials.password);
    setVisible(true);
    setEditing(false);
  }

  function cancelEditing() {
    if (credentials) {
      setUsername(credentials.username);
      setPassword(credentials.password);
    }
    setEditing(false);
    setError("");
  }

  async function copyValue(label: string, value: string) {
    await navigator.clipboard.writeText(value);
    setCopied(label);
    window.setTimeout(() => setCopied(""), 1500);
  }

  return (
    <div className="mt-4 rounded-lg border border-slate-200 bg-slate-50 p-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <p className="flex items-center gap-2 text-sm font-bold text-ink">
            <KeyRound size={16} className="text-brand" />
            Wakel AI login
          </p>
          <p className="mt-1 text-xs text-slate-500">Show the Docker runtime username and password for this workspace.</p>
        </div>
        <div className="flex flex-wrap gap-2">
          <Button type="button" variant="secondary" onClick={loadCredentials} disabled={loading || saving} className="shrink-0">
            {loading ? <Loader2 className="animate-spin" size={16} /> : visible ? <EyeOff size={16} /> : <Eye size={16} />}
            {loading ? "Loading..." : visible ? "Hide login" : "Show login"}
          </Button>
          <Button type="button" variant="secondary" onClick={startEditing} disabled={loading || saving} className="shrink-0">
            <KeyRound size={16} />
            Change password
          </Button>
        </div>
      </div>

      {error && <p className="mt-3 rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">{error}</p>}

      {editing && (
        <div className="mt-4 rounded-md border border-slate-200 bg-white p-3">
          <div className="grid gap-3 md:grid-cols-2">
            <div>
              <Label htmlFor={`runtime-username-${id}`}>Username</Label>
              <Input
                id={`runtime-username-${id}`}
                value={username}
                onChange={(event) => setUsername(event.target.value)}
                autoComplete="username"
                className="mt-1 font-mono"
              />
            </div>
            <div>
              <Label htmlFor={`runtime-password-${id}`}>New password</Label>
              <Input
                id={`runtime-password-${id}`}
                value={password}
                onChange={(event) => setPassword(event.target.value)}
                autoComplete="new-password"
                className="mt-1 font-mono"
              />
            </div>
          </div>
          <div className="mt-3 flex flex-wrap justify-end gap-2">
            <Button type="button" variant="secondary" onClick={cancelEditing} disabled={saving}>
              <X size={16} />
              Cancel
            </Button>
            <Button type="button" onClick={saveCredentials} disabled={saving}>
              {saving ? <Loader2 className="animate-spin" size={16} /> : <Save size={16} />}
              {saving ? "Updating..." : "Save password"}
            </Button>
          </div>
        </div>
      )}

      {credentials && visible && !editing && (
        <div className="mt-4 grid gap-3 md:grid-cols-2">
          <CredentialField label="Username" value={credentials.username} copied={copied === "username"} onCopy={() => copyValue("username", credentials.username)} />
          <CredentialField label="Password" value={credentials.password} copied={copied === "password"} onCopy={() => copyValue("password", credentials.password)} />
        </div>
      )}
    </div>
  );
}

function CredentialField({ label, value, copied, onCopy }: { label: string; value: string; copied: boolean; onCopy: () => void }) {
  return (
    <div className="rounded-md border border-slate-200 bg-white p-3">
      <div className="flex items-center justify-between gap-3">
        <div className="min-w-0">
          <p className="text-xs font-semibold uppercase text-slate-500">{label}</p>
          <p className="mt-1 truncate font-mono text-sm font-bold text-slate-900">{value}</p>
        </div>
        <button
          type="button"
          onClick={onCopy}
          className="focus-ring inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-slate-200 bg-white text-slate-600 hover:bg-slate-50"
          aria-label={`Copy ${label}`}
        >
          <Copy size={15} />
        </button>
      </div>
      {copied && <p className="mt-2 text-xs font-semibold text-emerald-700">Copied</p>}
    </div>
  );
}
