"use client";

import { useState, useEffect, useCallback } from "react";
import {
  getAdminTenantLDAPConfig,
  saveAdminTenantLDAPConfig,
  deleteAdminTenantLDAPConfig,
  testAdminTenantLDAPConfig,
  type TenantLDAPConfig,
  type LDAPTestResult,
} from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

interface TenantLDAPDialogProps {
  tenantID: number;
  onClose: () => void;
}

export function TenantLDAPDialog({ tenantID, onClose }: TenantLDAPDialogProps) {
  const [config, setConfig] = useState<TenantLDAPConfig | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [error, setError] = useState("");
  const [testResult, setTestResult] = useState<LDAPTestResult | null>(null);
  const [changePassword, setChangePassword] = useState(false);
  const [form, setForm] = useState<TenantLDAPConfig>({
    enabled: false,
    url: "ldap://",
    bind_dn: "",
    bind_password: "",
    base_dn: "",
    user_filter: "(sAMAccountName=%s)",
    tls: false,
    tls_skip_verify: false,
    default_role: "user",
    group_mappings: [],
  });

  const loadConfig = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const cfg = await getAdminTenantLDAPConfig(tenantID);
      if (cfg) {
        setConfig(cfg);
        setForm({ ...cfg, bind_password: "" });
        setChangePassword(false);
      }
    } catch {
      setError("LDAP-Konfiguration konnte nicht geladen werden.");
    } finally {
      setLoading(false);
    }
  }, [tenantID]);

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

  async function handleSave(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    setError("");
    try {
      const payload: Partial<TenantLDAPConfig> = { ...form };
      if (!changePassword) {
        delete payload.bind_password;
      }
      await saveAdminTenantLDAPConfig(tenantID, payload);
      await loadConfig();
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Speichern fehlgeschlagen.");
    } finally {
      setSaving(false);
    }
  }

  async function handleTest() {
    setTesting(true);
    setError("");
    setTestResult(null);
    try {
      const payload = config
        ? { use_saved: true }
        : { use_saved: false, ...form };
      const result = await testAdminTenantLDAPConfig(tenantID, payload as Parameters<typeof testAdminTenantLDAPConfig>[1]);
      setTestResult(result);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Test fehlgeschlagen.");
    } finally {
      setTesting(false);
    }
  }

  async function handleDelete() {
    setSaving(true);
    setError("");
    try {
      await deleteAdminTenantLDAPConfig(tenantID);
      setConfig(null);
      setForm({
        enabled: false, url: "ldap://", bind_dn: "", bind_password: "",
        base_dn: "", user_filter: "(sAMAccountName=%s)", tls: false,
        tls_skip_verify: false, default_role: "user", group_mappings: [],
      });
      setTestResult(null);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Löschen fehlgeschlagen.");
    } finally {
      setSaving(false);
    }
  }

  return (
    <Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
      <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>LDAP-Konfiguration (Mandant #{tenantID})</DialogTitle>
          <DialogDescription>LDAP-Server für diesen Mandanten konfigurieren.</DialogDescription>
        </DialogHeader>

        {error && (
          <Alert variant="destructive">
            <AlertDescription>{error}</AlertDescription>
          </Alert>
        )}

        {loading ? (
          <div className="space-y-3">
            {Array.from({ length: 6 }).map((_, i) => (
              <Skeleton key={i} className="h-10 w-full" />
            ))}
          </div>
        ) : (
          <form onSubmit={handleSave} className="space-y-4">
            <div className="flex items-center gap-2">
              <span className="text-sm text-muted-foreground">LDAP aktiviert</span>
              <input
                type="checkbox"
                className="h-4 w-4"
                checked={form.enabled}
                onChange={(e) => setForm((f) => ({ ...f, enabled: e.target.checked }))}
              />
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor={`atldap-url-${tenantID}`}>Server-URL</Label>
                <Input
                  id={`atldap-url-${tenantID}`}
                  placeholder="ldap://server:389  oder  ldaps://server:636"
                  value={form.url}
                  onChange={(e) => setForm((f) => ({ ...f, url: e.target.value }))}
                />
                <p className="text-xs text-muted-foreground">
                  Port frei wählbar · Standard: 389 (LDAP), 636 (LDAPS) · Univention UCS: 7389 / 7636
                </p>
              </div>
              <div className="space-y-2">
                <Label htmlFor={`atldap-bind-dn-${tenantID}`}>Bind-DN (Service-Account)</Label>
                <Input
                  id={`atldap-bind-dn-${tenantID}`}
                  placeholder="CN=archivmail,OU=Service,DC=example,DC=com"
                  value={form.bind_dn}
                  onChange={(e) => setForm((f) => ({ ...f, bind_dn: e.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor={`atldap-pw-${tenantID}`}>Bind-Passwort</Label>
                {config && !changePassword ? (
                  <div className="flex gap-2">
                    <Input id={`atldap-pw-${tenantID}`} type="password" value="••••••" readOnly className="flex-1" />
                    <Button type="button" variant="outline" size="sm" onClick={() => setChangePassword(true)}>
                      Ändern
                    </Button>
                  </div>
                ) : (
                  <Input
                    id={`atldap-pw-${tenantID}`}
                    type="password"
                    placeholder="Neues Passwort eingeben"
                    value={form.bind_password}
                    onChange={(e) => setForm((f) => ({ ...f, bind_password: e.target.value }))}
                  />
                )}
              </div>
              <div className="space-y-2">
                <Label htmlFor={`atldap-base-dn-${tenantID}`}>Base-DN</Label>
                <Input
                  id={`atldap-base-dn-${tenantID}`}
                  placeholder="DC=example,DC=com"
                  value={form.base_dn}
                  onChange={(e) => setForm((f) => ({ ...f, base_dn: e.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor={`atldap-filter-${tenantID}`}>User-Filter</Label>
                <Input
                  id={`atldap-filter-${tenantID}`}
                  placeholder="(sAMAccountName=%s)"
                  value={form.user_filter}
                  onChange={(e) => setForm((f) => ({ ...f, user_filter: e.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor={`atldap-role-${tenantID}`}>Standard-Rolle</Label>
                <Select
                  value={form.default_role}
                  onValueChange={(v) => setForm((f) => ({ ...f, default_role: v }))}
                >
                  <SelectTrigger id={`atldap-role-${tenantID}`}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="user">User</SelectItem>
                    <SelectItem value="auditor">Auditor</SelectItem>
                    <SelectItem value="domain_admin">Domain Admin</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>

            <Separator />

            <div className="flex flex-wrap gap-6">
              <label className="flex items-center gap-2 text-sm cursor-pointer">
                <input
                  type="checkbox"
                  className="h-4 w-4"
                  checked={form.tls}
                  onChange={(e) => setForm((f) => ({ ...f, tls: e.target.checked }))}
                />
                STARTTLS verwenden
              </label>
              <label className="flex items-center gap-2 text-sm cursor-pointer">
                <input
                  type="checkbox"
                  className="h-4 w-4"
                  checked={form.tls_skip_verify}
                  onChange={(e) => setForm((f) => ({ ...f, tls_skip_verify: e.target.checked }))}
                />
                TLS-Zertifikat ignorieren
                {form.tls_skip_verify && (
                  <Badge variant="destructive" className="text-xs ml-1">Unsicher</Badge>
                )}
              </label>
            </div>

            <Separator />

            {/* Group mappings -- superadmin per tenant: bis domain_admin */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label>Gruppen-Rollenzuordnung</Label>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() =>
                    setForm((f) => ({
                      ...f,
                      group_mappings: [...f.group_mappings, { group_dn: "", role: "user" }],
                    }))
                  }
                >
                  + Hinzufuegen
                </Button>
              </div>
              {form.group_mappings.length === 0 ? (
                <p className="text-sm text-muted-foreground">Keine Gruppen-Zuordnungen definiert.</p>
              ) : (
                <div className="space-y-2">
                  {form.group_mappings.map((gm, i) => (
                    <div key={i} className="flex gap-2 items-center">
                      <Input
                        className="flex-1"
                        placeholder="CN=Archivadmins,OU=Groups,DC=example,DC=com"
                        value={gm.group_dn}
                        onChange={(e) => {
                          const gms = [...form.group_mappings];
                          gms[i] = { ...gms[i], group_dn: e.target.value };
                          setForm((f) => ({ ...f, group_mappings: gms }));
                        }}
                      />
                      <Select
                        value={gm.role}
                        onValueChange={(v) => {
                          const gms = [...form.group_mappings];
                          gms[i] = { ...gms[i], role: v };
                          setForm((f) => ({ ...f, group_mappings: gms }));
                        }}
                      >
                        <SelectTrigger className="w-36">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="user">User</SelectItem>
                          <SelectItem value="auditor">Auditor</SelectItem>
                          <SelectItem value="domain_admin">Domain Admin</SelectItem>
                        </SelectContent>
                      </Select>
                      <Button
                        type="button"
                        variant="destructive"
                        size="sm"
                        onClick={() => {
                          const gms = form.group_mappings.filter((_, j) => j !== i);
                          setForm((f) => ({ ...f, group_mappings: gms }));
                        }}
                      >
                        Entfernen
                      </Button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Test result */}
            {testResult && (
              <Card>
                <CardContent className="pt-4 space-y-2">
                  <div className="flex items-center gap-2">
                    <Badge variant={testResult.ok ? "default" : "destructive"}>
                      {testResult.ok ? "Verbunden" : "Fehler"}
                    </Badge>
                    <span className="text-sm">{testResult.message}</span>
                    {testResult.latency_ms > 0 && (
                      <span className="text-xs text-muted-foreground">{testResult.latency_ms} ms</span>
                    )}
                  </div>
                  {testResult.server_info && (
                    <p className="text-xs text-muted-foreground font-mono">{testResult.server_info}</p>
                  )}
                  {testResult.users_found > 0 && (
                    <p className="text-sm">{testResult.users_found} Benutzer gefunden</p>
                  )}
                  {testResult.error_detail && (
                    <p className="text-xs text-destructive font-mono">{testResult.error_detail}</p>
                  )}
                </CardContent>
              </Card>
            )}

            {/* Action bar */}
            <div className="flex flex-wrap gap-2">
              <Button type="button" variant="outline" onClick={handleTest} disabled={testing || saving}>
                {testing ? "Teste..." : "Verbindung testen"}
              </Button>
              <Button type="submit" disabled={saving || testing}>
                {saving ? "Speichern..." : "Speichern"}
              </Button>
              {config && (
                <Button
                  type="button"
                  variant="destructive"
                  disabled={saving}
                  onClick={handleDelete}
                >
                  Konfiguration löschen
                </Button>
              )}
            </div>

            {config && (
              <p className="text-xs text-muted-foreground">
                Zuletzt geändert: {config.updated_at ? new Date(config.updated_at).toLocaleString("de-DE") : "–"}
                {config.updated_by ? ` von ${config.updated_by}` : ""}
              </p>
            )}
          </form>
        )}
      </DialogContent>
    </Dialog>
  );
}
