'use client'

import React, { useState, useEffect, useCallback } from 'react'
import { useSDK } from '@/lib/sdk'

// =============================================================================
// TYPES
// =============================================================================

interface Tenant {
  id: string
  name: string
  slug: string
  status: string
  user_limit: number
  llm_quota: number
  settings: Record<string, unknown>
  created_at: string
  updated_at: string
}

interface Namespace {
  id: string
  tenant_id: string
  name: string
  slug: string
  isolation_level: string
  classification: string
  created_at: string
}

interface Role {
  id: string
  name: string
  description: string
  is_system: boolean
  permissions: string[]
  created_at: string
}

interface UserRole {
  id: string
  user_id: string
  role_id: string
  role_name: string
  namespace_id: string | null
  expires_at: string | null
  created_at: string
}

interface LLMPolicy {
  id: string
  name: string
  description: string
  tenant_id: string
  namespace_id: string | null
  allowed_models: string[]
  blocked_models: string[]
  rate_limit_rpm: number
  rate_limit_tpd: number
  pii_detection_required: boolean
  pii_redaction_required: boolean
  max_tokens_per_request: number
  is_active: boolean
  created_at: string
  updated_at: string
}

type TabId = 'tenants' | 'namespaces' | 'roles' | 'users' | 'policies'

// =============================================================================
// API
// =============================================================================

const API = '/api/sdk/v1/rbac'

async function apiFetch<T>(path: string, opts?: RequestInit): Promise<T> {
  const res = await fetch(`${API}/${path}`, {
    headers: { 'Content-Type': 'application/json' },
    ...opts,
  })
  if (!res.ok) {
    const err = await res.text()
    throw new Error(`HTTP ${res.status}: ${err}`)
  }
  return res.json()
}

function formatDate(iso: string): string {
  return new Date(iso).toLocaleString('de-DE', {
    day: '2-digit', month: '2-digit', year: 'numeric',
  })
}

// =============================================================================
// MAIN PAGE
// =============================================================================

export default function RBACPage() {
  const { state } = useSDK()
  const [activeTab, setActiveTab] = useState<TabId>('tenants')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [success, setSuccess] = useState<string | null>(null)

  // Data
  const [tenants, setTenants] = useState<Tenant[]>([])
  const [selectedTenantId, setSelectedTenantId] = useState<string | null>(null)
  const [namespaces, setNamespaces] = useState<Namespace[]>([])
  const [roles, setRoles] = useState<Role[]>([])
  const [userRoles, setUserRoles] = useState<UserRole[]>([])
  const [policies, setPolicies] = useState<LLMPolicy[]>([])

  // Modals
  const [showTenantModal, setShowTenantModal] = useState(false)
  const [showNamespaceModal, setShowNamespaceModal] = useState(false)
  const [showRoleModal, setShowRoleModal] = useState(false)
  const [showUserRoleModal, setShowUserRoleModal] = useState(false)
  const [showPolicyModal, setShowPolicyModal] = useState(false)
  const [editingPolicy, setEditingPolicy] = useState<LLMPolicy | null>(null)

  // ─── Loaders ─────────────────────────────────────────────────────────

  const loadTenants = useCallback(async () => {
    setLoading(true); setError(null)
    try {
      const data = await apiFetch<Tenant[] | { tenants: Tenant[] }>('tenants')
      setTenants(Array.isArray(data) ? data : data.tenants || [])
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }, [])

  const loadNamespaces = useCallback(async (tenantId: string) => {
    setLoading(true); setError(null)
    try {
      const data = await apiFetch<Namespace[] | { namespaces: Namespace[] }>(`tenants/${tenantId}/namespaces`)
      setNamespaces(Array.isArray(data) ? data : data.namespaces || [])
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }, [])

  const loadRoles = useCallback(async () => {
    setLoading(true); setError(null)
    try {
      const data = await apiFetch<Role[] | { roles: Role[] }>('roles')
      setRoles(Array.isArray(data) ? data : data.roles || [])
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }, [])

  const loadUserRoles = useCallback(async () => {
    setLoading(true); setError(null)
    try {
      // Load for a specific user or all — the endpoint expects a userId
      // We'll load the current user's roles as default
      const data = await apiFetch<UserRole[] | { roles: UserRole[] }>('user-roles/00000000-0000-0000-0000-000000000001')
      setUserRoles(Array.isArray(data) ? data : data.roles || [])
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }, [])

  const loadPolicies = useCallback(async () => {
    setLoading(true); setError(null)
    try {
      const data = await apiFetch<LLMPolicy[] | { policies: LLMPolicy[] }>('llm/policies')
      setPolicies(Array.isArray(data) ? data : data.policies || [])
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }, [])

  useEffect(() => {
    if (activeTab === 'tenants') loadTenants()
    else if (activeTab === 'namespaces') { loadTenants(); if (selectedTenantId) loadNamespaces(selectedTenantId) }
    else if (activeTab === 'roles') loadRoles()
    else if (activeTab === 'users') loadUserRoles()
    else if (activeTab === 'policies') loadPolicies()
  }, [activeTab, loadTenants, loadNamespaces, loadRoles, loadUserRoles, loadPolicies, selectedTenantId])

  const showSuccessMsg = (msg: string) => {
    setSuccess(msg)
    setTimeout(() => setSuccess(null), 3000)
  }

  // ─── Actions ─────────────────────────────────────────────────────────

  const deleteLLMPolicy = async (id: string) => {
    if (!confirm('Policy wirklich loeschen?')) return
    try {
      await apiFetch(`llm/policies/${id}`, { method: 'DELETE' })
      showSuccessMsg('Policy geloescht')
      loadPolicies()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  const togglePolicyActive = async (policy: LLMPolicy) => {
    try {
      await apiFetch(`llm/policies/${policy.id}`, {
        method: 'PUT',
        body: JSON.stringify({ ...policy, is_active: !policy.is_active }),
      })
      loadPolicies()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  const revokeUserRole = async (userId: string, roleId: string) => {
    if (!confirm('Rolle wirklich entziehen?')) return
    try {
      await apiFetch(`user-roles/${userId}/${roleId}`, { method: 'DELETE' })
      showSuccessMsg('Rolle entzogen')
      loadUserRoles()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  // ─── Tabs ────────────────────────────────────────────────────────────

  const tabs: { id: TabId; label: string }[] = [
    { id: 'tenants', label: 'Mandanten' },
    { id: 'namespaces', label: 'Namespaces' },
    { id: 'roles', label: 'Rollen' },
    { id: 'users', label: 'Benutzer' },
    { id: 'policies', label: 'LLM-Policies' },
  ]

  return (
    <div className="p-6 max-w-7xl mx-auto">
      {/* Header */}
      <div className="mb-6">
        <h1 className="text-2xl font-bold text-gray-900">RBAC Administration</h1>
        <p className="text-gray-500 mt-1">Mandanten, Rollen, Berechtigungen und LLM-Policies verwalten</p>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 bg-gray-100 rounded-lg p-1 mb-6 overflow-x-auto">
        {tabs.map(tab => (
          <button
            key={tab.id}
            onClick={() => setActiveTab(tab.id)}
            className={`px-4 py-2 rounded-md text-sm font-medium transition-colors whitespace-nowrap ${
              activeTab === tab.id
                ? 'bg-white text-purple-700 shadow-sm'
                : 'text-gray-600 hover:text-gray-900'
            }`}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {error && <div className="mb-4 p-3 bg-red-50 text-red-700 rounded-lg text-sm">{error}</div>}
      {success && <div className="mb-4 p-3 bg-green-50 text-green-700 rounded-lg text-sm">{success}</div>}

      {loading && (
        <div className="flex items-center justify-center py-12">
          <div className="w-8 h-8 border-4 border-purple-200 border-t-purple-600 rounded-full animate-spin" />
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* TENANTS TAB */}
      {/* ══════════════════════════════════════════════════════════════════ */}
      {!loading && activeTab === 'tenants' && (
        <div>
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold">{tenants.length} Mandanten</h2>
            <button
              onClick={() => setShowTenantModal(true)}
              className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
            >
              + Mandant anlegen
            </button>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {tenants.map(t => (
              <div key={t.id} className="bg-white rounded-xl border border-gray-200 p-5">
                <div className="flex items-start justify-between mb-3">
                  <div>
                    <h3 className="font-semibold text-gray-900">{t.name}</h3>
                    <span className="text-xs font-mono text-gray-400">{t.slug}</span>
                  </div>
                  <span className={`px-2 py-0.5 rounded text-xs font-medium ${
                    t.status === 'active' ? 'bg-green-50 text-green-700' : 'bg-gray-100 text-gray-500'
                  }`}>
                    {t.status}
                  </span>
                </div>
                <div className="space-y-1 text-sm text-gray-600">
                  <div className="flex justify-between">
                    <span>User-Limit</span>
                    <span className="font-mono">{t.user_limit || 'unbegrenzt'}</span>
                  </div>
                  <div className="flex justify-between">
                    <span>LLM-Quota</span>
                    <span className="font-mono">{t.llm_quota || 'unbegrenzt'}</span>
                  </div>
                  <div className="flex justify-between">
                    <span>Erstellt</span>
                    <span>{formatDate(t.created_at)}</span>
                  </div>
                </div>
                <button
                  onClick={() => { setSelectedTenantId(t.id); setActiveTab('namespaces') }}
                  className="mt-3 w-full text-center text-sm text-purple-600 hover:text-purple-700 py-1"
                >
                  Namespaces anzeigen
                </button>
              </div>
            ))}
          </div>
          {tenants.length === 0 && (
            <div className="text-center py-12 text-gray-400">Keine Mandanten vorhanden</div>
          )}
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* NAMESPACES TAB */}
      {/* ══════════════════════════════════════════════════════════════════ */}
      {!loading && activeTab === 'namespaces' && (
        <div>
          <div className="flex items-center gap-4 mb-4">
            <select
              value={selectedTenantId || ''}
              onChange={e => { setSelectedTenantId(e.target.value); if (e.target.value) loadNamespaces(e.target.value) }}
              className="border border-gray-300 rounded-lg px-3 py-2 text-sm"
            >
              <option value="">Mandant waehlen...</option>
              {tenants.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
            </select>
            {selectedTenantId && (
              <button
                onClick={() => setShowNamespaceModal(true)}
                className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
              >
                + Namespace
              </button>
            )}
          </div>
          {!selectedTenantId ? (
            <div className="text-center py-12 text-gray-400">Bitte einen Mandanten waehlen</div>
          ) : (
            <div className="overflow-x-auto bg-white rounded-xl border border-gray-200">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-gray-200 bg-gray-50">
                    <th className="text-left px-4 py-3 font-medium text-gray-600">Name</th>
                    <th className="text-left px-4 py-3 font-medium text-gray-600">Slug</th>
                    <th className="text-left px-4 py-3 font-medium text-gray-600">Isolation</th>
                    <th className="text-left px-4 py-3 font-medium text-gray-600">Klassifikation</th>
                    <th className="text-left px-4 py-3 font-medium text-gray-600">Erstellt</th>
                  </tr>
                </thead>
                <tbody>
                  {namespaces.length === 0 ? (
                    <tr><td colSpan={5} className="text-center py-8 text-gray-400">Keine Namespaces</td></tr>
                  ) : namespaces.map(ns => (
                    <tr key={ns.id} className="border-b border-gray-100 hover:bg-gray-50">
                      <td className="px-4 py-3 font-medium">{ns.name}</td>
                      <td className="px-4 py-3 font-mono text-xs text-gray-500">{ns.slug}</td>
                      <td className="px-4 py-3">
                        <span className="px-2 py-0.5 bg-blue-50 text-blue-700 rounded text-xs">{ns.isolation_level}</span>
                      </td>
                      <td className="px-4 py-3">
                        <span className="px-2 py-0.5 bg-gray-100 text-gray-700 rounded text-xs">{ns.classification}</span>
                      </td>
                      <td className="px-4 py-3 text-gray-500">{formatDate(ns.created_at)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* ROLES TAB */}
      {/* ══════════════════════════════════════════════════════════════════ */}
      {!loading && activeTab === 'roles' && (
        <div>
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold">{roles.length} Rollen</h2>
            <button
              onClick={() => setShowRoleModal(true)}
              className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
            >
              + Rolle erstellen
            </button>
          </div>
          <div className="overflow-x-auto bg-white rounded-xl border border-gray-200">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 bg-gray-50">
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Name</th>
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Beschreibung</th>
                  <th className="text-center px-4 py-3 font-medium text-gray-600">Typ</th>
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Berechtigungen</th>
                </tr>
              </thead>
              <tbody>
                {roles.length === 0 ? (
                  <tr><td colSpan={4} className="text-center py-8 text-gray-400">Keine Rollen</td></tr>
                ) : roles.map(role => (
                  <tr key={role.id} className="border-b border-gray-100 hover:bg-gray-50">
                    <td className="px-4 py-3 font-medium">{role.name}</td>
                    <td className="px-4 py-3 text-gray-500 max-w-xs truncate">{role.description}</td>
                    <td className="px-4 py-3 text-center">
                      <span className={`px-2 py-0.5 rounded text-xs font-medium ${
                        role.is_system ? 'bg-purple-50 text-purple-700' : 'bg-gray-100 text-gray-600'
                      }`}>
                        {role.is_system ? 'System' : 'Custom'}
                      </span>
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex flex-wrap gap-1">
                        {(role.permissions || []).slice(0, 4).map(p => (
                          <span key={p} className="px-1.5 py-0.5 bg-gray-100 text-gray-600 rounded text-xs">{p}</span>
                        ))}
                        {(role.permissions || []).length > 4 && (
                          <span className="text-xs text-gray-400">+{role.permissions.length - 4}</span>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* USERS TAB */}
      {/* ══════════════════════════════════════════════════════════════════ */}
      {!loading && activeTab === 'users' && (
        <div>
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold">Benutzer-Rollen</h2>
            <button
              onClick={() => setShowUserRoleModal(true)}
              className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
            >
              + Rolle zuweisen
            </button>
          </div>

          {/* User ID lookup */}
          <div className="mb-4">
            <UserRoleLookup onLoad={(userId) => {
              setLoading(true)
              apiFetch<UserRole[] | { roles: UserRole[] }>(`user-roles/${userId}`)
                .then(data => setUserRoles(Array.isArray(data) ? data : data.roles || []))
                .catch(e => setError(e instanceof Error ? e.message : 'Fehler'))
                .finally(() => setLoading(false))
            }} />
          </div>

          <div className="overflow-x-auto bg-white rounded-xl border border-gray-200">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 bg-gray-50">
                  <th className="text-left px-4 py-3 font-medium text-gray-600">User-ID</th>
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Rolle</th>
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Namespace</th>
                  <th className="text-left px-4 py-3 font-medium text-gray-600">Ablauf</th>
                  <th className="text-center px-4 py-3 font-medium text-gray-600">Aktionen</th>
                </tr>
              </thead>
              <tbody>
                {userRoles.length === 0 ? (
                  <tr><td colSpan={5} className="text-center py-8 text-gray-400">Keine Rollen zugewiesen</td></tr>
                ) : userRoles.map(ur => (
                  <tr key={ur.id} className="border-b border-gray-100 hover:bg-gray-50">
                    <td className="px-4 py-3 font-mono text-xs">{ur.user_id}</td>
                    <td className="px-4 py-3">
                      <span className="px-2 py-0.5 bg-purple-50 text-purple-700 rounded text-xs font-medium">
                        {ur.role_name || ur.role_id}
                      </span>
                    </td>
                    <td className="px-4 py-3 font-mono text-xs text-gray-500">
                      {ur.namespace_id || 'Global'}
                    </td>
                    <td className="px-4 py-3 text-gray-500">
                      {ur.expires_at ? formatDate(ur.expires_at) : 'Unbegrenzt'}
                    </td>
                    <td className="px-4 py-3 text-center">
                      <button
                        onClick={() => revokeUserRole(ur.user_id, ur.role_id)}
                        className="text-red-600 hover:text-red-700 text-xs"
                      >
                        Entziehen
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* LLM POLICIES TAB */}
      {/* ══════════════════════════════════════════════════════════════════ */}
      {!loading && activeTab === 'policies' && (
        <div>
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold">{policies.length} LLM-Policies</h2>
            <button
              onClick={() => { setEditingPolicy(null); setShowPolicyModal(true) }}
              className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700"
            >
              + Policy erstellen
            </button>
          </div>
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
            {policies.map(policy => (
              <div key={policy.id} className={`bg-white rounded-xl border p-5 ${
                policy.is_active ? 'border-gray-200' : 'border-gray-100 opacity-60'
              }`}>
                <div className="flex items-start justify-between mb-3">
                  <div>
                    <h3 className="font-semibold text-gray-900">{policy.name}</h3>
                    <p className="text-xs text-gray-500 mt-0.5">{policy.description}</p>
                  </div>
                  <button
                    onClick={() => togglePolicyActive(policy)}
                    className={`px-2 py-0.5 rounded text-xs font-medium ${
                      policy.is_active ? 'bg-green-50 text-green-700' : 'bg-gray-100 text-gray-500'
                    }`}
                  >
                    {policy.is_active ? 'Aktiv' : 'Inaktiv'}
                  </button>
                </div>

                <div className="space-y-2 text-sm">
                  {(policy.allowed_models || []).length > 0 && (
                    <div>
                      <span className="text-gray-500">Erlaubte Models: </span>
                      <div className="flex flex-wrap gap-1 mt-1">
                        {policy.allowed_models.map(m => (
                          <span key={m} className="px-1.5 py-0.5 bg-blue-50 text-blue-700 rounded text-xs">{m}</span>
                        ))}
                      </div>
                    </div>
                  )}
                  <div className="flex justify-between text-gray-600">
                    <span>Rate-Limit</span>
                    <span className="font-mono text-xs">{policy.rate_limit_rpm} req/min, {policy.rate_limit_tpd} tok/tag</span>
                  </div>
                  <div className="flex justify-between text-gray-600">
                    <span>Max Tokens/Request</span>
                    <span className="font-mono text-xs">{policy.max_tokens_per_request}</span>
                  </div>
                  <div className="flex gap-3">
                    {policy.pii_detection_required && (
                      <span className="px-2 py-0.5 bg-amber-50 text-amber-700 rounded text-xs">PII-Erkennung</span>
                    )}
                    {policy.pii_redaction_required && (
                      <span className="px-2 py-0.5 bg-red-50 text-red-700 rounded text-xs">PII-Redaktion</span>
                    )}
                  </div>
                </div>

                <div className="flex justify-end gap-2 mt-3 pt-3 border-t border-gray-100">
                  <button
                    onClick={() => { setEditingPolicy(policy); setShowPolicyModal(true) }}
                    className="text-sm text-purple-600 hover:text-purple-700"
                  >
                    Bearbeiten
                  </button>
                  <button
                    onClick={() => deleteLLMPolicy(policy.id)}
                    className="text-sm text-red-600 hover:text-red-700"
                  >
                    Loeschen
                  </button>
                </div>
              </div>
            ))}
          </div>
          {policies.length === 0 && (
            <div className="text-center py-12 text-gray-400">Keine LLM-Policies vorhanden</div>
          )}
        </div>
      )}

      {/* ══════════════════════════════════════════════════════════════════ */}
      {/* MODALS */}
      {/* ══════════════════════════════════════════════════════════════════ */}

      {showTenantModal && (
        <CreateTenantModal
          onClose={() => setShowTenantModal(false)}
          onCreated={() => { setShowTenantModal(false); showSuccessMsg('Mandant erstellt'); loadTenants() }}
        />
      )}
      {showNamespaceModal && selectedTenantId && (
        <CreateNamespaceModal
          tenantId={selectedTenantId}
          onClose={() => setShowNamespaceModal(false)}
          onCreated={() => { setShowNamespaceModal(false); showSuccessMsg('Namespace erstellt'); loadNamespaces(selectedTenantId) }}
        />
      )}
      {showRoleModal && (
        <CreateRoleModal
          onClose={() => setShowRoleModal(false)}
          onCreated={() => { setShowRoleModal(false); showSuccessMsg('Rolle erstellt'); loadRoles() }}
        />
      )}
      {showUserRoleModal && (
        <AssignRoleModal
          onClose={() => setShowUserRoleModal(false)}
          onAssigned={() => { setShowUserRoleModal(false); showSuccessMsg('Rolle zugewiesen'); loadUserRoles() }}
        />
      )}
      {showPolicyModal && (
        <PolicyModal
          existing={editingPolicy}
          onClose={() => { setShowPolicyModal(false); setEditingPolicy(null) }}
          onSaved={() => { setShowPolicyModal(false); setEditingPolicy(null); showSuccessMsg('Policy gespeichert'); loadPolicies() }}
        />
      )}
    </div>
  )
}

// =============================================================================
// USER ROLE LOOKUP
// =============================================================================

function UserRoleLookup({ onLoad }: { onLoad: (userId: string) => void }) {
  const [userId, setUserId] = useState('00000000-0000-0000-0000-000000000001')
  return (
    <div className="flex gap-2">
      <input
        type="text"
        value={userId}
        onChange={e => setUserId(e.target.value)}
        placeholder="User-ID eingeben..."
        className="border border-gray-300 rounded-lg px-3 py-2 text-sm flex-1 font-mono"
      />
      <button
        onClick={() => onLoad(userId)}
        className="px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm"
      >
        Laden
      </button>
    </div>
  )
}

// =============================================================================
// MODAL BASE
// =============================================================================

function ModalBase({ title, onClose, children }: { title: string; onClose: () => void; children: React.ReactNode }) {
  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
      <div className="bg-white rounded-xl shadow-xl max-w-lg w-full max-h-[90vh] overflow-y-auto">
        <div className="flex items-center justify-between p-5 border-b border-gray-200">
          <h3 className="text-lg font-semibold">{title}</h3>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl">&times;</button>
        </div>
        <div className="p-5">{children}</div>
      </div>
    </div>
  )
}

// =============================================================================
// CREATE TENANT MODAL
// =============================================================================

function CreateTenantModal({ onClose, onCreated }: { onClose: () => void; onCreated: () => void }) {
  const [form, setForm] = useState({ name: '', slug: '', user_limit: 100, llm_quota: 100000 })
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async () => {
    if (!form.name || !form.slug) { setError('Name und Slug sind Pflichtfelder'); return }
    setSaving(true)
    try {
      await apiFetch('tenants', { method: 'POST', body: JSON.stringify(form) })
      onCreated()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  return (
    <ModalBase title="Mandant anlegen" onClose={onClose}>
      {error && <div className="mb-3 p-2 bg-red-50 text-red-700 rounded text-sm">{error}</div>}
      <div className="space-y-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Name</label>
          <input type="text" value={form.name} onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Slug</label>
          <input type="text" value={form.slug} onChange={e => setForm(f => ({ ...f, slug: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">User-Limit</label>
            <input type="number" value={form.user_limit} onChange={e => setForm(f => ({ ...f, user_limit: +e.target.value }))}
              className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">LLM-Quota</label>
            <input type="number" value={form.llm_quota} onChange={e => setForm(f => ({ ...f, llm_quota: +e.target.value }))}
              className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
          </div>
        </div>
      </div>
      <div className="flex justify-end gap-2 mt-5">
        <button onClick={onClose} className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Abbrechen</button>
        <button onClick={handleSubmit} disabled={saving}
          className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
          {saving ? 'Speichern...' : 'Erstellen'}
        </button>
      </div>
    </ModalBase>
  )
}

// =============================================================================
// CREATE NAMESPACE MODAL
// =============================================================================

function CreateNamespaceModal({ tenantId, onClose, onCreated }: { tenantId: string; onClose: () => void; onCreated: () => void }) {
  const [form, setForm] = useState({ name: '', slug: '', isolation_level: 'shared', classification: 'internal' })
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async () => {
    if (!form.name) { setError('Name ist Pflichtfeld'); return }
    setSaving(true)
    try {
      await apiFetch(`tenants/${tenantId}/namespaces`, { method: 'POST', body: JSON.stringify(form) })
      onCreated()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  return (
    <ModalBase title="Namespace erstellen" onClose={onClose}>
      {error && <div className="mb-3 p-2 bg-red-50 text-red-700 rounded text-sm">{error}</div>}
      <div className="space-y-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Name</label>
          <input type="text" value={form.name} onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Slug</label>
          <input type="text" value={form.slug} onChange={e => setForm(f => ({ ...f, slug: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Isolation</label>
          <select value={form.isolation_level} onChange={e => setForm(f => ({ ...f, isolation_level: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm">
            <option value="shared">Shared</option>
            <option value="isolated">Isolated</option>
            <option value="strict">Strict</option>
          </select>
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Klassifikation</label>
          <select value={form.classification} onChange={e => setForm(f => ({ ...f, classification: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm">
            <option value="public">Public</option>
            <option value="internal">Internal</option>
            <option value="confidential">Confidential</option>
            <option value="restricted">Restricted</option>
          </select>
        </div>
      </div>
      <div className="flex justify-end gap-2 mt-5">
        <button onClick={onClose} className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Abbrechen</button>
        <button onClick={handleSubmit} disabled={saving}
          className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
          {saving ? 'Speichern...' : 'Erstellen'}
        </button>
      </div>
    </ModalBase>
  )
}

// =============================================================================
// CREATE ROLE MODAL
// =============================================================================

function CreateRoleModal({ onClose, onCreated }: { onClose: () => void; onCreated: () => void }) {
  const [form, setForm] = useState({ name: '', description: '', permissions: '' })
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async () => {
    if (!form.name) { setError('Name ist Pflichtfeld'); return }
    setSaving(true)
    try {
      await apiFetch('roles', {
        method: 'POST',
        body: JSON.stringify({
          name: form.name,
          description: form.description,
          permissions: form.permissions.split(',').map(s => s.trim()).filter(Boolean),
        }),
      })
      onCreated()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  return (
    <ModalBase title="Rolle erstellen" onClose={onClose}>
      {error && <div className="mb-3 p-2 bg-red-50 text-red-700 rounded text-sm">{error}</div>}
      <div className="space-y-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Name</label>
          <input type="text" value={form.name} onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Beschreibung</label>
          <input type="text" value={form.description} onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Berechtigungen (kommagetrennt)</label>
          <textarea value={form.permissions} onChange={e => setForm(f => ({ ...f, permissions: e.target.value }))}
            placeholder="llm:read, llm:write, audit:read"
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono h-20" />
        </div>
      </div>
      <div className="flex justify-end gap-2 mt-5">
        <button onClick={onClose} className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Abbrechen</button>
        <button onClick={handleSubmit} disabled={saving}
          className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
          {saving ? 'Speichern...' : 'Erstellen'}
        </button>
      </div>
    </ModalBase>
  )
}

// =============================================================================
// ASSIGN ROLE MODAL
// =============================================================================

function AssignRoleModal({ onClose, onAssigned }: { onClose: () => void; onAssigned: () => void }) {
  const [form, setForm] = useState({ user_id: '', role_id: '', namespace_id: '', expires_at: '' })
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async () => {
    if (!form.user_id || !form.role_id) { setError('User-ID und Rolle sind Pflichtfelder'); return }
    setSaving(true)
    try {
      await apiFetch('user-roles', {
        method: 'POST',
        body: JSON.stringify({
          user_id: form.user_id,
          role_id: form.role_id,
          namespace_id: form.namespace_id || null,
          expires_at: form.expires_at || null,
        }),
      })
      onAssigned()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  return (
    <ModalBase title="Rolle zuweisen" onClose={onClose}>
      {error && <div className="mb-3 p-2 bg-red-50 text-red-700 rounded text-sm">{error}</div>}
      <div className="space-y-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">User-ID</label>
          <input type="text" value={form.user_id} onChange={e => setForm(f => ({ ...f, user_id: e.target.value }))}
            placeholder="UUID" className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Rollen-ID</label>
          <input type="text" value={form.role_id} onChange={e => setForm(f => ({ ...f, role_id: e.target.value }))}
            placeholder="UUID" className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Namespace-ID (optional)</label>
          <input type="text" value={form.namespace_id} onChange={e => setForm(f => ({ ...f, namespace_id: e.target.value }))}
            placeholder="Leer = Global" className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Ablaufdatum (optional)</label>
          <input type="date" value={form.expires_at} onChange={e => setForm(f => ({ ...f, expires_at: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
      </div>
      <div className="flex justify-end gap-2 mt-5">
        <button onClick={onClose} className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Abbrechen</button>
        <button onClick={handleSubmit} disabled={saving}
          className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
          {saving ? 'Speichern...' : 'Zuweisen'}
        </button>
      </div>
    </ModalBase>
  )
}

// =============================================================================
// POLICY MODAL (Create / Edit)
// =============================================================================

function PolicyModal({ existing, onClose, onSaved }: { existing: LLMPolicy | null; onClose: () => void; onSaved: () => void }) {
  const [form, setForm] = useState({
    name: existing?.name || '',
    description: existing?.description || '',
    allowed_models: (existing?.allowed_models || []).join(', '),
    blocked_models: (existing?.blocked_models || []).join(', '),
    rate_limit_rpm: existing?.rate_limit_rpm ?? 60,
    rate_limit_tpd: existing?.rate_limit_tpd ?? 1000000,
    max_tokens_per_request: existing?.max_tokens_per_request ?? 4096,
    pii_detection_required: existing?.pii_detection_required ?? true,
    pii_redaction_required: existing?.pii_redaction_required ?? false,
    is_active: existing?.is_active ?? true,
  })
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async () => {
    if (!form.name) { setError('Name ist Pflichtfeld'); return }
    setSaving(true)
    try {
      const body = {
        ...form,
        allowed_models: form.allowed_models.split(',').map(s => s.trim()).filter(Boolean),
        blocked_models: form.blocked_models.split(',').map(s => s.trim()).filter(Boolean),
      }
      if (existing) {
        await apiFetch(`llm/policies/${existing.id}`, { method: 'PUT', body: JSON.stringify(body) })
      } else {
        await apiFetch('llm/policies', { method: 'POST', body: JSON.stringify(body) })
      }
      onSaved()
    } catch (e) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  return (
    <ModalBase title={existing ? 'Policy bearbeiten' : 'Policy erstellen'} onClose={onClose}>
      {error && <div className="mb-3 p-2 bg-red-50 text-red-700 rounded text-sm">{error}</div>}
      <div className="space-y-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Name</label>
          <input type="text" value={form.name} onChange={e => setForm(f => ({ ...f, name: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Beschreibung</label>
          <input type="text" value={form.description} onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Erlaubte Models (kommagetrennt)</label>
          <input type="text" value={form.allowed_models} onChange={e => setForm(f => ({ ...f, allowed_models: e.target.value }))}
            placeholder="qwen3:30b-a3b, claude-sonnet-4-5"
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Blockierte Models (kommagetrennt)</label>
          <input type="text" value={form.blocked_models} onChange={e => setForm(f => ({ ...f, blocked_models: e.target.value }))}
            className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono" />
        </div>
        <div className="grid grid-cols-3 gap-3">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Rate (req/min)</label>
            <input type="number" value={form.rate_limit_rpm} onChange={e => setForm(f => ({ ...f, rate_limit_rpm: +e.target.value }))}
              className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Tokens/Tag</label>
            <input type="number" value={form.rate_limit_tpd} onChange={e => setForm(f => ({ ...f, rate_limit_tpd: +e.target.value }))}
              className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Max Tok/Req</label>
            <input type="number" value={form.max_tokens_per_request} onChange={e => setForm(f => ({ ...f, max_tokens_per_request: +e.target.value }))}
              className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm" />
          </div>
        </div>
        <div className="flex gap-4">
          <label className="flex items-center gap-2 text-sm">
            <input type="checkbox" checked={form.pii_detection_required}
              onChange={e => setForm(f => ({ ...f, pii_detection_required: e.target.checked }))}
              className="rounded border-gray-300" />
            PII-Erkennung
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input type="checkbox" checked={form.pii_redaction_required}
              onChange={e => setForm(f => ({ ...f, pii_redaction_required: e.target.checked }))}
              className="rounded border-gray-300" />
            PII-Redaktion
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input type="checkbox" checked={form.is_active}
              onChange={e => setForm(f => ({ ...f, is_active: e.target.checked }))}
              className="rounded border-gray-300" />
            Aktiv
          </label>
        </div>
      </div>
      <div className="flex justify-end gap-2 mt-5">
        <button onClick={onClose} className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800">Abbrechen</button>
        <button onClick={handleSubmit} disabled={saving}
          className="px-4 py-2 bg-purple-600 text-white rounded-lg text-sm hover:bg-purple-700 disabled:opacity-50">
          {saving ? 'Speichern...' : (existing ? 'Aktualisieren' : 'Erstellen')}
        </button>
      </div>
    </ModalBase>
  )
}
