"use client";

import { useEffect, useState } from "react";
import { CREDENTIAL_TYPES, generateSlug, isValidSlug } from "@/lib/credential-types";
import type { CredentialTypeDef } from "@/lib/credential-types";

interface CredentialInstance {
  id: string;
  type: string;
  name: string;
  slug: string;
  client: string;
  description: string | null;
  updatedAt: string;
  fields: { fieldKey: string }[];
}

type FormMode = "list" | "add" | "edit";

export default function CredentialsPage() {
  const [instances, setInstances] = useState<CredentialInstance[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  // Form state
  const [mode, setMode] = useState<FormMode>("list");
  const [editId, setEditId] = useState<string | null>(null);
  const [selectedType, setSelectedType] = useState<string | null>(null);
  const [formName, setFormName] = useState("");
  const [formSlug, setFormSlug] = useState("");
  const [formSlugManual, setFormSlugManual] = useState(false);
  const [formClient, setFormClient] = useState("");
  const [formDescription, setFormDescription] = useState("");
  const [formFields, setFormFields] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);

  async function loadInstances() {
    const res = await fetch("/api/credentials");
    setInstances(await res.json());
    setLoading(false);
  }

  useEffect(() => { loadInstances(); }, []);

  function resetForm() {
    setMode("list");
    setEditId(null);
    setSelectedType(null);
    setFormName("");
    setFormSlug("");
    setFormSlugManual(false);
    setFormClient("");
    setFormDescription("");
    setFormFields({});
    setError("");
  }

  function startAdd(type: string) {
    setSelectedType(type);
    setMode("add");
    setEditId(null);
    setFormName("");
    setFormSlug("");
    setFormSlugManual(false);
    setFormClient("");
    setFormDescription("");
    setFormFields({});
    setError("");
  }

  function startEdit(inst: CredentialInstance) {
    setSelectedType(inst.type);
    setMode("edit");
    setEditId(inst.id);
    setFormName(inst.name);
    setFormSlug(inst.slug);
    setFormSlugManual(true); // Don't auto-generate when editing
    setFormClient(inst.client);
    setFormDescription(inst.description || "");
    setFormFields({}); // Don't pre-fill secret values
    setError("");
  }

  function handleClientChange(value: string) {
    setFormClient(value);
    if (!formSlugManual) {
      setFormSlug(generateSlug(value));
    }
  }

  async function handleSave() {
    const typeDef = selectedType ? CREDENTIAL_TYPES[selectedType] : null;
    if (!typeDef) return;

    if (!formClient.trim()) { setError("Client / project is required"); return; }
    if (!formName.trim()) { setError("Name is required"); return; }
    if (!isValidSlug(formSlug)) { setError("Env var prefix must be 1-20 uppercase letters/numbers, starting with a letter"); return; }

    // Validate required fields (only for new credentials)
    if (mode === "add") {
      for (const field of typeDef.fields) {
        if (field.required && (!formFields[field.key] || !formFields[field.key].trim())) {
          setError(`"${field.label}" is required`);
          return;
        }
      }
    }

    setSaving(true);
    setError("");

    try {
      const body: Record<string, any> = {
        type: selectedType,
        name: formName.trim(),
        slug: formSlug,
        client: formClient.trim(),
        description: formDescription.trim() || null,
      };

      // Only include fields that have values
      const fieldsToSend: Record<string, string> = {};
      for (const [key, value] of Object.entries(formFields)) {
        if (value && value.trim()) fieldsToSend[key] = value;
      }
      if (Object.keys(fieldsToSend).length > 0) {
        body.fields = fieldsToSend;
      }

      const url = mode === "edit" ? `/api/credentials/${editId}` : "/api/credentials";
      const method = mode === "edit" ? "PATCH" : "POST";

      // For new credentials, fields is required
      if (mode === "add") body.fields = fieldsToSend;

      const res = await fetch(url, {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });

      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        setError(data.error || "Failed to save");
        setSaving(false);
        return;
      }

      await loadInstances();
      resetForm();
    } catch (err: any) {
      setError(err.message);
    }
    setSaving(false);
  }

  async function handleDelete(id: string, name: string) {
    if (!confirm(`Delete credential "${name}"? This cannot be undone.`)) return;
    await fetch(`/api/credentials/${id}`, { method: "DELETE" });
    if (editId === id) resetForm();
    await loadInstances();
  }

  // Group instances by type
  const byType: Record<string, CredentialInstance[]> = {};
  for (const inst of instances) {
    if (!byType[inst.type]) byType[inst.type] = [];
    byType[inst.type].push(inst);
  }

  if (loading) return <div className="container"><p className="text-muted">Loading...</p></div>;

  const typeDef = selectedType ? CREDENTIAL_TYPES[selectedType] : null;

  // Check for slug collision with existing instances of the same type
  const slugConflict = selectedType && formSlug
    ? instances.some((inst) => inst.type === selectedType && inst.slug === formSlug && inst.id !== editId)
    : false;

  return (
    <div>
      <h1 className="mb-6">Credentials</h1>

      {/* Info card */}
      <div className="card mb-6">
        <p style={{ marginTop: 0 }}>
          Credentials are structured, typed connections to external services (e.g. Snowflake, GitHub, Airflow).
          Each credential is tied to a client or project and injected as named environment variables into your bot sessions.
        </p>
        <p className="text-muted text-sm" style={{ marginBottom: 0 }}>
          For generic environment variables (API keys, custom values), use the <a href="/settings/secrets">Secrets</a> page instead.
        </p>
      </div>

      {/* Existing credentials by type */}
      {Object.entries(CREDENTIAL_TYPES).map(([type, def]) => {
        const typeInstances = byType[type] || [];
        if (typeInstances.length === 0) return null;
        return (
          <div key={type} className="mb-6">
            <h2 className="mb-4">{def.icon} {def.label}</h2>
            {typeInstances.map((inst) => (
              <div key={inst.id} className="card mb-4">
                <div className="flex justify-between items-center">
                  <div>
                    <strong>{inst.name}</strong>
                    <span className="badge badge-muted" style={{ marginLeft: "0.75rem" }}>{inst.slug}</span>
                  </div>
                  <div className="flex gap-2">
                    <button className="btn" onClick={() => startEdit(inst)} style={{ fontSize: "0.85rem" }}>Edit</button>
                    <button className="btn btn-danger" onClick={() => handleDelete(inst.id, inst.name)} style={{ fontSize: "0.85rem" }}>Delete</button>
                  </div>
                </div>
                <p className="text-sm text-muted mt-1">
                  <strong>Client:</strong> {inst.client}
                  {inst.description && <> &mdash; {inst.description}</>}
                </p>
                <p className="text-sm text-muted mt-1">
                  {inst.fields.length} field{inst.fields.length !== 1 ? "s" : ""} configured
                  &middot; Updated {new Date(inst.updatedAt).toLocaleDateString()}
                </p>
                {/* Show env var preview */}
                <div className="text-sm text-mono mt-2" style={{ color: "var(--text-muted)", fontSize: "0.8rem" }}>
                  {def.fields.filter((f) => inst.fields.some((ff) => ff.fieldKey === f.key)).map((f) => (
                    <span key={f.key} style={{ marginRight: "1rem" }}>{def.envVarPattern(inst.slug, f.key)}</span>
                  ))}
                </div>
              </div>
            ))}
          </div>
        );
      })}

      {/* Add / Edit form */}
      {mode === "list" ? (
        <div className="card">
          <h2 style={{ marginTop: 0 }}>Add Credential</h2>
          <p className="text-muted text-sm mb-4">Choose a credential type to get started:</p>
          <div style={{ display: "flex", flexWrap: "wrap", gap: "0.5rem" }}>
            {Object.values(CREDENTIAL_TYPES).map((def) => (
              <button
                key={def.type}
                className="btn"
                onClick={() => startAdd(def.type)}
              >
                {def.icon} {def.label}
              </button>
            ))}
          </div>
        </div>
      ) : typeDef ? (
        <div className="card">
          <div className="flex justify-between items-center mb-4">
            <h2 style={{ marginTop: 0, marginBottom: 0 }}>
              {mode === "edit" ? "Edit" : "Add"} {typeDef.icon} {typeDef.label} Credential
            </h2>
            <button className="btn" onClick={resetForm} style={{ fontSize: "0.85rem" }}>Cancel</button>
          </div>
          <p className="text-muted text-sm mb-4">{typeDef.description}</p>

          {/* Client / Project — prominent */}
          <div className="mb-4">
            <label className="label" htmlFor="cred-client">Client / Project *</label>
            <input
              id="cred-client"
              className="input"
              value={formClient}
              onChange={(e) => handleClientChange(e.target.value)}
              placeholder="e.g. Client X, Project Alpha"
            />
          </div>

          {/* Instance Name */}
          <div className="mb-4">
            <label className="label" htmlFor="cred-name">Display Name *</label>
            <input
              id="cred-name"
              className="input"
              value={formName}
              onChange={(e) => setFormName(e.target.value)}
              placeholder={`e.g. ${formClient || "Client X"} ${typeDef.label}`}
            />
          </div>

          {/* Env Var Prefix */}
          <div className="mb-4">
            <label className="label" htmlFor="cred-slug">Env Var Prefix *</label>
            <div className="flex gap-2 items-center">
              <input
                id="cred-slug"
                className="input"
                value={formSlug}
                onChange={(e) => { setFormSlug(e.target.value.toUpperCase()); setFormSlugManual(true); }}
                placeholder="CLIENTX"
                style={{ fontFamily: "var(--font-mono)", maxWidth: "200px" }}
              />
              <span className="text-sm text-muted">
                e.g. {typeDef.fields[0] ? typeDef.envVarPattern(formSlug || "PREFIX", typeDef.fields[0].key) : ""}
              </span>
            </div>
            {slugConflict ? (
              <p className="text-sm mt-1" style={{ color: "var(--danger)" }}>
                A {typeDef?.label} credential with this prefix already exists. Change the client name or edit the prefix.
              </p>
            ) : (
              <p className="text-muted text-sm mt-1">Auto-generated from client name. Edit to customize.</p>
            )}
          </div>

          {/* Description */}
          <div className="mb-4">
            <label className="label" htmlFor="cred-desc">Description (optional)</label>
            <textarea
              id="cred-desc"
              className="input"
              value={formDescription}
              onChange={(e) => setFormDescription(e.target.value)}
              rows={2}
              placeholder="Additional notes about this credential..."
            />
          </div>

          {/* Type-specific fields */}
          <h3 className="mb-4" style={{ marginTop: "1.5rem" }}>Connection Fields</h3>
          {mode === "edit" && (
            <p className="text-muted text-sm mb-4">Leave fields blank to keep existing values.</p>
          )}
          {typeDef.fields.map((field) => (
            <div key={field.key} className="mb-4">
              <label className="label" htmlFor={`field-${field.key}`}>
                {field.label}{field.required ? " *" : ""}
              </label>
              {field.multiline ? (
                <textarea
                  id={`field-${field.key}`}
                  className="input"
                  value={formFields[field.key] || ""}
                  onChange={(e) => setFormFields({ ...formFields, [field.key]: e.target.value })}
                  placeholder={field.placeholder || ""}
                  rows={6}
                  style={{ fontFamily: "var(--font-mono)", fontSize: "0.85rem" }}
                />
              ) : (
                <input
                  id={`field-${field.key}`}
                  className="input"
                  type={field.isSecret ? "password" : "text"}
                  value={formFields[field.key] || ""}
                  onChange={(e) => setFormFields({ ...formFields, [field.key]: e.target.value })}
                  placeholder={field.placeholder || ""}
                />
              )}
              {field.helpText && (
                <p className="text-muted text-sm mt-1">{field.helpText}</p>
              )}
              <p className="text-mono text-sm mt-1" style={{ color: "var(--text-muted)", fontSize: "0.8rem" }}>
                → {typeDef.envVarPattern(formSlug || "PREFIX", field.key)}
              </p>
            </div>
          ))}

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

          <button className="btn btn-primary" onClick={handleSave} disabled={saving || slugConflict}>
            {saving ? "Saving..." : mode === "edit" ? "Update Credential" : "Save Credential"}
          </button>
        </div>
      ) : null}
    </div>
  );
}
