"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/ui/Icon";
import {
  createVaultEntryAction,
  updateVaultEntryAction,
  setVaultSharesAction,
} from "@/lib/vault/actions";
import type { VaultEntryDTO } from "@/lib/vault/queries";
import { SharePicker, type ShareTargets } from "@/components/ui/SharePicker";
import { PasswordGenerator, strengthOf } from "./PasswordGenerator";

const PIN_PATTERN = /^[0-9]{4,8}$/;

/** Grobe Stärkeschätzung für ein frei eingegebenes Passwort. */
function estimateBits(pw: string): number {
  if (!pw) return 0;
  let pool = 0;
  if (/[a-z]/.test(pw)) pool += 26;
  if (/[A-Z]/.test(pw)) pool += 26;
  if (/[0-9]/.test(pw)) pool += 10;
  if (/[^a-zA-Z0-9]/.test(pw)) pool += 25;
  return pool > 1 ? Math.round(pw.length * Math.log2(pool)) : 0;
}

function Section({
  icon,
  title,
  hint,
  children,
}: {
  icon: string;
  title: string;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <section className="form-section">
      <div className="form-section-head">
        <Icon name={icon} size={14} />
        {title}
        {hint ? <span className="text-muted ml-auto normal-case tracking-normal">{hint}</span> : null}
      </div>
      {children}
    </section>
  );
}

export function VaultDrawer({
  entry,
  targets,
  categories,
  canShare,
  onClose,
}: {
  entry: VaultEntryDTO | null;
  targets: ShareTargets;
  categories: string[];
  canShare: boolean;
  onClose: () => void;
}) {
  const router = useRouter();
  const isNew = !entry;

  const [title, setTitle] = useState(entry?.title ?? "");
  const [username, setUsername] = useState(entry?.username ?? "");
  const [url, setUrl] = useState(entry?.url ?? "");
  const [category, setCategory] = useState(entry?.category ?? "");
  const [notes, setNotes] = useState(entry?.notes ?? "");
  const [secret, setSecret] = useState("");
  const [showSecret, setShowSecret] = useState(isNew);
  const [showGenerator, setShowGenerator] = useState(isNew);

  const [pinMode, setPinMode] = useState<"none" | "set" | "keep">(isNew ? "none" : "keep");
  const [pin, setPin] = useState("");
  const [pinHint, setPinHint] = useState(entry?.pinHint ?? "");
  const [currentPin, setCurrentPin] = useState("");

  const [userIds, setUserIds] = useState<string[]>(entry?.users.map((u) => u.id) ?? []);
  const [teamIds, setTeamIds] = useState<string[]>(entry?.teams.map((t) => t.id) ?? []);
  const [roleIds, setRoleIds] = useState<string[]>(entry?.roles.map((r) => r.id) ?? []);
  const [shareEdit, setShareEdit] = useState(entry?.shareEdit ?? false);

  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const showShares = canShare && (isNew || entry!.canShare);
  const needsCurrentPin = !isNew && entry!.pinProtected && pinMode !== "keep" && !secret.trim();

  const bits = secret ? estimateBits(secret) : 0;
  const strength = strengthOf(bits);

  const save = async () => {
    setError(null);
    if (!title.trim()) return setError("Titel darf nicht leer sein.");
    if (isNew && !secret.trim()) return setError("Bitte ein Passwort eingeben oder erzeugen.");
    if (pinMode === "set" && !PIN_PATTERN.test(pin)) {
      return setError("PIN muss aus 4–8 Ziffern bestehen.");
    }
    if (needsCurrentPin && !PIN_PATTERN.test(currentPin)) {
      return setError("Bitte die aktuelle PIN eingeben, um den Schutz zu ändern.");
    }

    setSaving(true);
    const payload = {
      title,
      username,
      url,
      category,
      notes,
      secret: secret.trim() || null,
      pinMode,
      pin: pinMode === "set" ? pin : null,
      pinHint,
      currentPin: currentPin || null,
    };

    const res = isNew
      ? await createVaultEntryAction(payload)
      : await updateVaultEntryAction(entry!.id, payload);

    if (res.error) {
      setSaving(false);
      return setError(res.error);
    }

    const entryId = res.id ?? entry?.id;
    if (showShares && entryId) {
      const shareRes = await setVaultSharesAction(entryId, {
        userIds,
        teamIds,
        roleIds,
        canEdit: shareEdit,
      });
      if (shareRes.error) {
        setSaving(false);
        return setError(shareRes.error);
      }
    }

    setSaving(false);
    onClose();
    router.refresh();
  };

  const shareCount = userIds.length + teamIds.length + roleIds.length;

  return (
    <div className="drawer-overlay" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className="drawer drawer-vault animate-in">
        {/* Kopf */}
        <div className="mb-5 flex items-start justify-between gap-3">
          <div className="flex items-center gap-3">
            <span className="vault-mark" style={{ color: "var(--blue)" }}>
              <Icon name={isNew ? "plus" : "edit"} size={18} />
            </span>
            <div>
              <span className="eyebrow">{isNew ? "Neuer Eintrag" : "Bearbeiten"}</span>
              <h2 className="mt-0.5" style={{ fontSize: "1.2rem" }}>
                {title.trim() || "Zugangsdaten"}
              </h2>
            </div>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Schließen">
            <Icon name="close" size={16} />
          </button>
        </div>

        {error ? <p className="field-error mb-3">{error}</p> : null}

        <div className="flex flex-col gap-3">
          {/* ── Zugang ── */}
          <Section icon="globe" title="Zugang">
            <div className="field">
              <label className="label">Titel</label>
              <input
                className="input"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="z. B. Instagram Avaria"
                autoFocus={isNew}
              />
            </div>
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              <div className="field">
                <label className="label">Benutzer / E-Mail</label>
                <input
                  className="input"
                  value={username}
                  onChange={(e) => setUsername(e.target.value)}
                  placeholder="name@avaria-media.de"
                  autoComplete="off"
                />
              </div>
              <div className="field">
                <label className="label">Kategorie</label>
                <input
                  className="input"
                  value={category}
                  onChange={(e) => setCategory(e.target.value)}
                  placeholder="z. B. Social Media"
                  list="vault-categories"
                />
                <datalist id="vault-categories">
                  {categories.map((c) => (
                    <option key={c} value={c} />
                  ))}
                </datalist>
              </div>
            </div>
            <div className="field">
              <label className="label">URL</label>
              <input
                className="input"
                value={url}
                onChange={(e) => setUrl(e.target.value)}
                placeholder="https://…"
              />
            </div>
          </Section>

          {/* ── Passwort ── */}
          <Section
            icon="key"
            title="Passwort"
            hint={isNew ? undefined : "leer = unverändert"}
          >
            <div className="flex items-center gap-2">
              <input
                className="input vault-mono flex-1"
                type={showSecret ? "text" : "password"}
                value={secret}
                onChange={(e) => setSecret(e.target.value)}
                placeholder={isNew ? "Eingeben oder erzeugen" : "••••••••"}
                autoComplete="new-password"
                spellCheck={false}
              />
              <button
                type="button"
                className="btn btn-ghost btn-sm"
                onClick={() => setShowSecret((v) => !v)}
                title={showSecret ? "Verbergen" : "Anzeigen"}
              >
                <Icon name="eye" size={15} />
              </button>
              <button
                type="button"
                className="btn btn-ghost btn-sm"
                data-active={showGenerator}
                onClick={() => setShowGenerator((v) => !v)}
                title="Generator ein-/ausblenden"
              >
                <Icon name="activity" size={15} />
              </button>
            </div>

            {secret ? (
              <div className="flex items-center gap-2">
                <div
                  className="h-1 flex-1 overflow-hidden rounded-full"
                  style={{ background: "rgba(255,255,255,.08)" }}
                >
                  <div
                    className="h-full rounded-full transition-all"
                    style={{ width: `${strength.pct}%`, background: strength.color }}
                  />
                </div>
                <span className="text-xs font-bold" style={{ color: strength.color }}>
                  {bits} Bit · {strength.label}
                </span>
              </div>
            ) : null}

            {showGenerator ? (
              <PasswordGenerator
                onUse={(v) => {
                  setSecret(v);
                  setShowSecret(true);
                }}
              />
            ) : null}
          </Section>

          {/* ── PIN-Schutz ── */}
          <Section icon="lock" title="Zusätzlicher PIN-Schutz" hint="4–8 Ziffern">
            <div className="flex flex-wrap gap-2">
              {!isNew && entry!.pinProtected ? (
                <button
                  type="button"
                  className="pill"
                  data-active={pinMode === "keep"}
                  onClick={() => setPinMode("keep")}
                >
                  <Icon name="check" size={14} /> PIN beibehalten
                </button>
              ) : null}
              <button
                type="button"
                className="pill"
                data-active={pinMode === "none"}
                onClick={() => setPinMode("none")}
              >
                Ohne PIN
              </button>
              <button
                type="button"
                className="pill"
                data-active={pinMode === "set"}
                onClick={() => setPinMode("set")}
              >
                <Icon name="lock" size={14} />
                {entry?.pinProtected ? "Neue PIN" : "Mit PIN schützen"}
              </button>
            </div>

            {pinMode === "set" ? (
              <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                <div className="field">
                  <label className="label">PIN</label>
                  <input
                    className="input vault-mono"
                    inputMode="numeric"
                    maxLength={8}
                    value={pin}
                    onChange={(e) => setPin(e.target.value.replace(/\D/g, ""))}
                    placeholder="4–8 Ziffern"
                    autoComplete="off"
                  />
                </div>
                <div className="field">
                  <label className="label">Hinweis (optional)</label>
                  <input
                    className="input"
                    value={pinHint}
                    onChange={(e) => setPinHint(e.target.value)}
                    placeholder="kein PIN-Klartext!"
                    maxLength={80}
                  />
                </div>
              </div>
            ) : null}

            {needsCurrentPin ? (
              <div className="field">
                <label className="label">Aktuelle PIN zur Bestätigung</label>
                <input
                  className="input vault-mono"
                  inputMode="numeric"
                  maxLength={8}
                  value={currentPin}
                  onChange={(e) => setCurrentPin(e.target.value.replace(/\D/g, ""))}
                  placeholder="••••"
                  autoComplete="off"
                />
              </div>
            ) : null}

            <p className="text-muted text-xs">
              Mit PIN wird das Passwort ein zweites Mal verschlüsselt — ohne sie kann es
              niemand lesen, auch keine Administration. Geht die PIN verloren, ist der
              Eintrag unwiderruflich verloren.
            </p>
          </Section>

          {/* ── Freigaben ── */}
          {showShares ? (
            <Section
              icon="users"
              title="Freigaben"
              hint={shareCount > 0 ? `${shareCount} ausgewählt` : "nur für dich"}
            >
              <SharePicker
                targets={targets}
                userIds={userIds}
                teamIds={teamIds}
                roleIds={roleIds}
                onUsers={setUserIds}
                onTeams={setTeamIds}
                onRoles={setRoleIds}
              />

              {shareCount > 0 ? (
                <div className="flex flex-col gap-2">
                  <span className="gen-label">Rechte der Freigegebenen</span>
                  <div className="segmented self-start">
                    <button
                      type="button"
                      className="segmented-btn"
                      data-active={!shareEdit}
                      onClick={() => setShareEdit(false)}
                    >
                      <Icon name="eye" size={14} /> Nur lesen
                    </button>
                    <button
                      type="button"
                      className="segmented-btn"
                      data-active={shareEdit}
                      onClick={() => setShareEdit(true)}
                    >
                      <Icon name="edit" size={14} /> Bearbeiten
                    </button>
                  </div>
                  <p className="text-muted text-xs">
                    {shareEdit
                      ? "Freigegebene können Titel, Passwort und Notiz ändern — löschen und weiterverteilen bleibt bei dir."
                      : "Freigegebene können den Eintrag sehen und das Passwort kopieren."}
                  </p>
                </div>
              ) : null}
            </Section>
          ) : null}

          {/* ── Notiz ── */}
          <Section icon="list" title="Notiz" hint="unverschlüsselt">
            <textarea
              className="textarea"
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              placeholder="Hinweise zum Zugang — keine Geheimnisse hier ablegen."
              style={{ minHeight: 74 }}
            />
          </Section>
        </div>

        <div className="form-footer">
          <span className="text-muted text-xs">
            {pinMode === "set" || (pinMode === "keep" && entry?.pinProtected)
              ? "Doppelt verschlüsselt (Server + PIN)"
              : "Verschlüsselt gespeichert"}
          </span>
          <div className="flex items-center gap-2">
            <button className="btn btn-ghost" onClick={onClose} disabled={saving}>
              Abbrechen
            </button>
            <button className="btn btn-primary" onClick={save} disabled={saving || !title.trim()}>
              {saving ? "Speichern …" : isNew ? "Anlegen" : "Speichern"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

