import { useState, useEffect, useRef, useMemo } from 'react'
import { BrowserRouter as Router, Routes, Route, Link, useLocation, useNavigate } from 'react-router-dom'
import {
  LayoutDashboard, Building2, LogOut,
  Plus, Edit2, X, ExternalLink, Menu,
  ChevronRight, ArrowUpRight, UserPlus,
  AlertTriangle, Trash2, Copy, Download, ChevronDown,
} from 'lucide-react'
import axios from 'axios'

// ── Central de captura de logs ────────────────────────────────────────────────
//
// Bus singleton: agrega erros JS, promise rejections, falhas axios e
// console.error. Persiste em localStorage (cap 200 FIFO). Componentes se
// inscrevem via useErrorLogs() e re-renderizam ao receber novos logs.

type LogLevel  = 'error' | 'warn' | 'info'
type LogSource = 'js' | 'promise' | 'axios' | 'console' | 'manual'

interface LogEntry {
  id: string
  ts: number
  level: LogLevel
  source: LogSource
  message: string
  stack?: string
  meta?: Record<string, any>
}

const LOGS_LS_KEY = 'sa_error_logs_v1'
const LOGS_MAX    = 200

function safeStringify(v: any, max = 800): string {
  try {
    if (typeof v === 'string') return v
    if (v instanceof Error) return v.message
    const seen = new WeakSet()
    const out = JSON.stringify(v, (_k, val) => {
      if (typeof val === 'object' && val !== null) {
        if (seen.has(val)) return '[Circular]'
        seen.add(val)
      }
      return val
    })
    return out.length > max ? out.slice(0, max) + '…' : out
  } catch { return String(v) }
}

function loadLogs(): LogEntry[] {
  try {
    const raw = localStorage.getItem(LOGS_LS_KEY)
    if (!raw) return []
    const parsed = JSON.parse(raw)
    return Array.isArray(parsed) ? parsed : []
  } catch { return [] }
}

const errorBus = (() => {
  let logs: LogEntry[] = loadLogs()
  const listeners = new Set<() => void>()
  const persist = () => {
    try { localStorage.setItem(LOGS_LS_KEY, JSON.stringify(logs.slice(0, LOGS_MAX))) }
    catch { /* quota exceeded — ignora */ }
  }
  const notify = () => listeners.forEach(fn => { try { fn() } catch {} })

  return {
    add(entry: Omit<LogEntry, 'id' | 'ts'>) {
      const log: LogEntry = {
        ...entry,
        id: Math.random().toString(36).slice(2, 10) + Date.now().toString(36),
        ts: Date.now(),
      }
      logs = [log, ...logs].slice(0, LOGS_MAX)
      persist(); notify()
      return log
    },
    clear() { logs = []; persist(); notify() },
    getAll() { return logs },
    subscribe(fn: () => void) {
      listeners.add(fn)
      return () => { listeners.delete(fn) }
    },
  }
})()

let _captureInstalled = false
function installErrorCapture() {
  if (_captureInstalled || typeof window === 'undefined') return
  _captureInstalled = true

  // ── window.onerror (JS exceptions sem catch) ────────────────────────────
  window.addEventListener('error', (e: ErrorEvent) => {
    // Ignora erros de assets (script/img) — barulho que não importa aqui
    if ((e as any).target && (e as any).target !== window) return
    errorBus.add({
      level: 'error',
      source: 'js',
      message: e.message || 'Erro de runtime',
      stack: e.error?.stack,
      meta: {
        filename: e.filename,
        line: e.lineno,
        col: e.colno,
        url: window.location.pathname,
      },
    })
  })

  // ── unhandled promise rejections ─────────────────────────────────────────
  window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {
    const r: any = e.reason
    errorBus.add({
      level: 'error',
      source: 'promise',
      message: typeof r === 'string' ? r : (r?.message || 'Promise rejeitada sem catch'),
      stack: r?.stack,
      meta: { url: window.location.pathname },
    })
  })

  // ── console.error (intercepta sem recursão) ──────────────────────────────
  const origErr = console.error.bind(console)
  console.error = (...args: any[]) => {
    try {
      const first = args[0]
      // Filtra ruído conhecido do React (warnings de hydration / strict mode)
      const noise = typeof first === 'string' && (
        first.startsWith('Warning:') ||
        first.includes('act(') ||
        first.includes('React Router')
      )
      if (!noise) {
        errorBus.add({
          level: 'error',
          source: 'console',
          message: args.map(a => safeStringify(a, 400)).join(' '),
          stack: args.find(a => a instanceof Error)?.stack,
        })
      }
    } catch { /* nunca derruba a chamada original */ }
    origErr(...args)
  }

  // ── console.warn (só captura warnings explícitos) ───────────────────────
  const origWarn = console.warn.bind(console)
  console.warn = (...args: any[]) => {
    try {
      const first = args[0]
      const noise = typeof first === 'string' && first.startsWith('Warning:')
      if (!noise) {
        errorBus.add({
          level: 'warn',
          source: 'console',
          message: args.map(a => safeStringify(a, 400)).join(' '),
        })
      }
    } catch {}
    origWarn(...args)
  }
}
installErrorCapture()

// ── API axios + captura de falhas ─────────────────────────────────────────────

const api = axios.create({ baseURL: '/superadmin/api', withCredentials: true })
api.interceptors.response.use(r => r, err => {
  if (err.response?.status === 401) window.dispatchEvent(new CustomEvent('sa:logout'))

  // Não loga 401 na rota /me — é o probe de sessão, comportamento esperado
  const isAuthProbe = err.config?.url?.endsWith('/me') && err.response?.status === 401
  if (!isAuthProbe) {
    const status = err.response?.status
    const method = (err.config?.method || 'GET').toUpperCase()
    const url    = err.config?.url || '?'
    errorBus.add({
      level: 'error',
      source: 'axios',
      message: `${method} ${url} → ${status ?? 'sem resposta'} ${err.response?.statusText || err.message || ''}`.trim(),
      stack: err.stack,
      meta: {
        method, url, status,
        data: err.response?.data,
        request_data: typeof err.config?.data === 'string' ? safeStringify(err.config.data, 300) : undefined,
      },
    })
  }
  return Promise.reject(err)
})

// ── Types ─────────────────────────────────────────────────────────────────────

interface Tenant {
  id: number; slug: string; name: string; domain: string | null; active: boolean;
  primary_color: string; secondary_color: string; logo_url: string | null;
  contact_email: string | null; contact_phone: string | null; app_url: string | null;
}

interface TenantStats {
  users: number; orders: number; revenue: number; tickets_sold: number; club_members: number;
}

// ── API helpers ───────────────────────────────────────────────────────────────

const SA = {
  login:    (email: string, password: string) => api.post('/login', { email, password }).then(r => r.data),
  logout:   () => api.post('/logout'),
  me:       () => api.get('/me').then(r => r.data),
  tenants:  () => api.get('/tenants').then(r => r.data) as Promise<Tenant[]>,
  stats:    (id: number) => api.get(`/tenants/${id}/stats`).then(r => r.data) as Promise<TenantStats>,
  create:   (data: any) => api.post('/tenants', data).then(r => r.data),
  update:   (id: number, data: any) => api.put(`/tenants/${id}`, data).then(r => r.data),
  remove:   (id: number) => api.delete(`/tenants/${id}`).then(r => r.data),
  createAdmin: (tenantId: number, data: any) => api.post(`/tenants/${tenantId}/admins`, data).then(r => r.data),
}

// ── Hooks ─────────────────────────────────────────────────────────────────────

function useCountUp(target: number, duration = 1000) {
  const [value, setValue] = useState(0)
  const startRef = useRef<number | null>(null)
  const targetRef = useRef(target)
  useEffect(() => {
    targetRef.current = target
    startRef.current = null
    let raf = 0
    const step = (t: number) => {
      if (startRef.current === null) startRef.current = t
      const p = Math.min((t - startRef.current) / duration, 1)
      const eased = 1 - Math.pow(1 - p, 3)
      setValue(Math.floor(eased * targetRef.current))
      if (p < 1) raf = requestAnimationFrame(step)
    }
    raf = requestAnimationFrame(step)
    return () => cancelAnimationFrame(raf)
  }, [target, duration])
  return value
}

function useTick(intervalMs = 1000) {
  const [, set] = useState(0)
  useEffect(() => {
    const id = setInterval(() => set(x => x + 1), intervalMs)
    return () => clearInterval(id)
  }, [intervalMs])
}

// ── Number formatting ─────────────────────────────────────────────────────────

const pad2 = (n: number) => String(n).padStart(2, '0')
const fmtBRL = (n: number) => {
  if (n >= 1000) return 'R$' + (n / 1000).toFixed(1).replace('.', ',') + 'k'
  return 'R$' + Math.round(n)
}

// ── Telemetry strip (top global) ──────────────────────────────────────────────

function TelemetryStrip({ status = 'ONLINE' as 'ONLINE' | 'CONNECTING' | 'OFFLINE' }) {
  // boot fake estável dentro da sessão
  const bootRef = useRef(Date.now() - (14 * 86400 + 3 * 3600 + Math.floor(Math.random() * 1800)) * 1000)
  const syncRef = useRef(Date.now())
  useTick(1000)

  const upMs = Date.now() - bootRef.current
  const days  = Math.floor(upMs / 86_400_000)
  const hours = Math.floor((upMs % 86_400_000) / 3_600_000)
  const ago   = Math.floor((Date.now() - syncRef.current) / 1000)
  const time  = new Date().toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit', second: '2-digit' })

  const dotColor = status === 'ONLINE' ? 'bg-acid-500' : status === 'CONNECTING' ? 'bg-amber-500' : 'bg-coral-500'
  const txtColor = status === 'ONLINE' ? 'text-acid-500' : status === 'CONNECTING' ? 'text-amber-500' : 'text-coral-500'

  return (
    <div className="relative z-10 flex items-center gap-3 sm:gap-4 px-3 sm:px-6 h-7 border-b border-ink-800/80 bg-ink-950 font-mono text-[10px] uppercase tracking-[0.18em] text-ink-500 overflow-hidden whitespace-nowrap">
      <span className="flex items-center gap-1.5 shrink-0">
        <span className={`w-1.5 h-1.5 rounded-full ${dotColor} animate-blink`} />
        <span className="text-ink-300">SYS-01</span>
      </span>
      <span className="text-ink-700">/</span>
      <span className="shrink-0">ALEMÃO · NUVEM SAAS</span>
      <span className="text-ink-700 hidden xs:inline">/</span>
      <span className={`${txtColor} shrink-0`}>{status}</span>
      <span className="text-ink-700 hidden sm:inline">/</span>
      <span className="hidden sm:inline shrink-0">UPTIME {days}D {pad2(hours)}H</span>
      <span className="text-ink-700 hidden md:inline">/</span>
      <span className="hidden md:inline shrink-0">SYNC {ago}s</span>
      <span className="text-ink-700 ml-auto hidden lg:inline">/</span>
      <span className="hidden lg:inline shrink-0 text-ink-300 tabular">{time} BRT</span>
    </div>
  )
}

// ── Login Page ────────────────────────────────────────────────────────────────

function LoginPage({ onLogin }: { onLogin: () => void }) {
  const [email, setEmail] = useState('')
  const [pass, setPass]   = useState('')
  const [err, setErr]     = useState('')
  const [loading, setLoading] = useState(false)

  async function submit(e: React.FormEvent) {
    e.preventDefault()
    setLoading(true); setErr('')
    try {
      await SA.login(email, pass)
      onLogin()
    } catch (e: any) {
      setErr(e.response?.data?.error || 'Falha ao autenticar')
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="relative min-h-screen bg-ink-950 text-ink-100 noise overflow-hidden">
      <TelemetryStrip status={loading ? 'CONNECTING' : 'OFFLINE'} />

      <div className="absolute inset-0 bg-grid bg-grid-fade pointer-events-none" />

      {/* faixa decorativa lateral */}
      <div className="absolute top-7 bottom-0 left-0 w-px bg-gradient-to-b from-acid-500/40 via-acid-500/5 to-transparent" />

      <div className="relative z-10 flex items-center justify-center px-6 py-16 min-h-[calc(100vh-1.75rem)]">
        <div className="w-full max-w-[420px] animate-fade-up">

          {/* Mark editorial */}
          <div className="flex items-baseline gap-2 mb-8">
            <span className="font-mono text-[10px] uppercase tracking-[0.3em] text-acid-500">/01</span>
            <span className="font-mono text-[10px] uppercase tracking-[0.3em] text-ink-400">acesso · console</span>
            <span className="ml-auto font-mono text-[10px] uppercase tracking-[0.3em] text-ink-500">v1.0</span>
          </div>

          <h1 className="leading-[0.85] mb-6">
            <span className="block font-display text-ink-50 text-[68px] tracking-tight">Super</span>
            <span className="block font-display-italic text-acid-500 text-[68px] -mt-2">admin.</span>
          </h1>

          <div className="flex items-center gap-3 mb-10">
            <div className="h-px flex-1 bg-ink-700" />
            <span className="font-mono text-[10px] uppercase tracking-[0.3em] text-ink-400">multi-tenant</span>
            <div className="h-px flex-1 bg-ink-700" />
          </div>

          <form onSubmit={submit} className="space-y-7">
            <FieldUnderline
              label="Email"
              type="email"
              value={email}
              onChange={setEmail}
              placeholder="super@admin.local"
              autoFocus
              required
            />
            <FieldUnderline
              label="Senha"
              type="password"
              value={pass}
              onChange={setPass}
              placeholder="••••••••••"
              required
            />

            {err && (
              <div className="flex items-center gap-2 font-mono text-[11px] uppercase tracking-wider text-coral-400 animate-fade-in">
                <span className="w-1 h-1 bg-coral-500 animate-blink" />
                <span>{err}</span>
              </div>
            )}

            <button
              type="submit"
              disabled={loading}
              className="group relative w-full flex items-center justify-between gap-3 px-5 py-4 border border-acid-500 bg-transparent hover:bg-acid-500 text-acid-500 hover:text-ink-950 transition-colors duration-300 disabled:opacity-40 disabled:cursor-not-allowed focus-acid"
            >
              <span className="font-mono text-[11px] uppercase tracking-[0.3em]">
                {loading ? 'autenticando…' : 'entrar no sistema'}
              </span>
              <ArrowUpRight size={18} className="transition-transform duration-300 group-hover:rotate-45" />
              {/* canto inferior direito tick */}
              <span className="absolute bottom-1 right-1 w-2 h-2 border-r border-b border-current opacity-50 transition-opacity group-hover:opacity-100" />
              <span className="absolute top-1 left-1 w-2 h-2 border-l border-t border-current opacity-50 transition-opacity group-hover:opacity-100" />
            </button>
          </form>

          <p className="mt-12 font-mono text-[10px] uppercase tracking-[0.25em] text-ink-500 leading-[1.8]">
            ↳ Acesso restrito · operadores autorizados<br />
            <span className="text-ink-600">Toda atividade é registrada.</span>
          </p>
        </div>
      </div>
    </div>
  )
}

// ── Underline-style input ─────────────────────────────────────────────────────

function FieldUnderline({
  label, type = 'text', value, onChange, placeholder, required, autoFocus,
}: {
  label: string; type?: string; value: string;
  onChange: (v: string) => void;
  placeholder?: string; required?: boolean; autoFocus?: boolean;
}) {
  const [focused, setFocused] = useState(false)
  return (
    <label className="block group">
      <span className="block font-mono text-[10px] uppercase tracking-[0.28em] text-ink-400 mb-2">
        {label}{required ? <span className="text-acid-500"> *</span> : null}
      </span>
      <div className="relative">
        <input
          type={type}
          value={value}
          required={required}
          autoFocus={autoFocus}
          placeholder={placeholder}
          onChange={e => onChange(e.target.value)}
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          className="w-full bg-transparent border-0 outline-none px-0 py-2 text-ink-50 text-base placeholder:text-ink-600 placeholder:font-light"
        />
        <span className="absolute left-0 right-0 bottom-0 h-px bg-ink-700" />
        <span
          className="absolute left-0 bottom-0 h-px bg-acid-500 transition-transform duration-500 origin-left"
          style={{ transform: focused ? 'scaleX(1)' : 'scaleX(0)', width: '100%' }}
        />
      </div>
    </label>
  )
}

// Versão "boxed" para dentro de modais (mais compacto, mesmo idioma visual)
function FieldBoxed({
  label, type = 'text', value, onChange, required, name,
}: {
  label: string; type?: string; value: string;
  onChange: (v: string) => void;
  required?: boolean; name?: string;
}) {
  return (
    <label className="block">
      <span className="block font-mono text-[10px] uppercase tracking-[0.28em] text-ink-400 mb-1.5">
        {label}{required ? <span className="text-acid-500"> *</span> : null}
      </span>
      <input
        type={type}
        name={name}
        value={value}
        required={required}
        onChange={e => onChange(e.target.value)}
        className="w-full bg-ink-900 border border-ink-700 px-3 py-2.5 text-sm text-ink-50 placeholder:text-ink-600 focus:outline-none focus:border-acid-500 transition-colors"
      />
    </label>
  )
}

// ── Tenant Modal ──────────────────────────────────────────────────────────────

function TenantModal({ tenant, onClose, onSaved }: {
  tenant: Tenant | null; onClose: () => void; onSaved: () => void
}) {
  const isEdit = !!tenant
  const [form, setForm] = useState({
    slug: tenant?.slug || '',
    name: tenant?.name || '',
    domain: tenant?.domain || '',
    active: tenant?.active ?? true,
    primary_color:   tenant?.primary_color   || '#f59e0b',
    secondary_color: tenant?.secondary_color || '#10b981',
    logo_url:        tenant?.logo_url        || '',
    contact_email:   tenant?.contact_email   || '',
    contact_phone:   tenant?.contact_phone   || '',
    app_url:         tenant?.app_url         || '',
  })
  const [saving, setSaving] = useState(false)

  const set = (k: keyof typeof form) => (v: any) =>
    setForm(f => ({ ...f, [k]: typeof v === 'object' && v?.target ? v.target.value : v }))

  async function submit(e: React.FormEvent) {
    e.preventDefault(); setSaving(true)
    try {
      if (isEdit) await SA.update(tenant!.id, form)
      else await SA.create(form)
      onSaved(); onClose()
    } catch (err: any) {
      alert(err.response?.data?.error || 'Erro ao salvar')
    } finally { setSaving(false) }
  }

  return (
    <ModalShell onClose={onClose} title={isEdit ? 'Editar empresa' : 'Nova empresa'} subtitle={isEdit ? `#${tenant!.id} · ${tenant!.slug}` : 'tenant cadastro · console'}>
      <form onSubmit={submit} className="p-6 space-y-5">
        <div className="grid grid-cols-2 gap-3">
          <FieldBoxed label="Slug" value={form.slug} onChange={set('slug')} required={!isEdit} />
          <FieldBoxed label="Nome" value={form.name} onChange={set('name')} required />
        </div>
        <FieldBoxed label="Domínio" value={form.domain} onChange={set('domain')} />
        <FieldBoxed label="URL da aplicação" value={form.app_url} onChange={set('app_url')} />
        <div className="grid grid-cols-2 gap-3">
          <FieldBoxed label="Email contato" type="email" value={form.contact_email} onChange={set('contact_email')} />
          <FieldBoxed label="Telefone contato" value={form.contact_phone} onChange={set('contact_phone')} />
        </div>
        <FieldBoxed label="Logo URL" value={form.logo_url} onChange={set('logo_url')} />

        <div className="grid grid-cols-2 gap-3">
          <ColorPicker label="Primária"   value={form.primary_color}   onChange={set('primary_color')} />
          <ColorPicker label="Secundária" value={form.secondary_color} onChange={set('secondary_color')} />
        </div>

        {/* Branding preview — agora editorial */}
        <div className="border border-ink-700 bg-ink-900">
          <div className="flex items-center gap-3 px-4 py-3 border-b border-ink-800" style={{ borderLeftWidth: 0, boxShadow: `inset 4px 0 0 ${form.primary_color}` }}>
            {form.logo_url
              ? <img src={form.logo_url} alt="" className="h-7 object-contain" />
              : <span className="font-display text-ink-50 text-base">{form.name || 'Prévia'}</span>}
            <span className="ml-auto font-mono text-[9px] uppercase tracking-[0.25em] text-ink-500">prévia</span>
          </div>
          <div className="h-1.5" style={{ background: form.secondary_color, opacity: 0.55 }} />
        </div>

        {isEdit && (
          <label className="flex items-center gap-2.5 cursor-pointer select-none group pt-1">
            <span className={`relative w-9 h-5 border ${form.active ? 'bg-acid-500/15 border-acid-500' : 'bg-ink-900 border-ink-700'} transition-colors`}>
              <span className={`absolute top-0.5 ${form.active ? 'left-[18px] bg-acid-500' : 'left-0.5 bg-ink-500'} w-3.5 h-3.5 transition-all`} />
            </span>
            <input type="checkbox" checked={form.active}
              onChange={e => setForm(f => ({ ...f, active: e.target.checked }))}
              className="sr-only" />
            <span className="font-mono text-[10px] uppercase tracking-[0.25em] text-ink-300">
              empresa {form.active ? 'ativa' : 'inativa'}
            </span>
          </label>
        )}

        <div className="flex gap-3 pt-3 border-t border-ink-800">
          <button type="button" onClick={onClose}
            className="flex-1 py-3 border border-ink-700 hover:border-ink-500 text-ink-300 hover:text-ink-50 font-mono text-[10px] uppercase tracking-[0.28em] transition-colors">
            Cancelar
          </button>
          <button type="submit" disabled={saving}
            className="flex-1 py-3 border border-acid-500 bg-acid-500 hover:bg-acid-400 text-ink-950 font-mono text-[10px] uppercase tracking-[0.28em] disabled:opacity-50 transition-colors">
            {saving ? 'salvando…' : 'salvar'}
          </button>
        </div>
      </form>
    </ModalShell>
  )
}

function ColorPicker({ label, value, onChange }: { label: string; value: string; onChange: (v: any) => void }) {
  return (
    <div>
      <span className="block font-mono text-[10px] uppercase tracking-[0.28em] text-ink-400 mb-1.5">{label}</span>
      <div className="flex items-stretch gap-0 border border-ink-700 focus-within:border-acid-500 transition-colors">
        <label className="relative w-11 cursor-pointer overflow-hidden" style={{ background: value }}>
          <input type="color" value={value} onChange={onChange}
            className="absolute inset-0 opacity-0 cursor-pointer w-full h-full" />
        </label>
        <input value={value} onChange={onChange}
          className="flex-1 bg-ink-900 px-3 py-2.5 font-mono text-xs text-ink-50 focus:outline-none uppercase" />
      </div>
    </div>
  )
}

// ── Create Admin Modal ────────────────────────────────────────────────────────

function CreateAdminModal({ tenantId, tenantName, onClose }: {
  tenantId: number; tenantName: string; onClose: () => void
}) {
  const [form, setForm] = useState({ username: '', password: '', name: '' })
  const [saving, setSaving] = useState(false)

  const set = (k: keyof typeof form) => (v: string) => setForm(f => ({ ...f, [k]: v }))

  async function submit(e: React.FormEvent) {
    e.preventDefault(); setSaving(true)
    try {
      await SA.createAdmin(tenantId, form)
      onClose()
    } catch (err: any) {
      alert(err.response?.data?.error || 'Erro ao criar admin')
    } finally { setSaving(false) }
  }

  return (
    <ModalShell onClose={onClose} title="Novo admin" subtitle={`para · ${tenantName}`} size="sm">
      <form onSubmit={submit} className="p-6 space-y-4">
        <FieldBoxed label="Usuário"   value={form.username} onChange={set('username')} required />
        <FieldBoxed label="Nome"      value={form.name}     onChange={set('name')}     required />
        <FieldBoxed label="Senha"     value={form.password} onChange={set('password')} type="password" required />

        <div className="flex gap-3 pt-3 border-t border-ink-800">
          <button type="button" onClick={onClose}
            className="flex-1 py-3 border border-ink-700 hover:border-ink-500 text-ink-300 hover:text-ink-50 font-mono text-[10px] uppercase tracking-[0.28em] transition-colors">
            Cancelar
          </button>
          <button type="submit" disabled={saving}
            className="flex-1 py-3 border border-acid-500 bg-acid-500 hover:bg-acid-400 text-ink-950 font-mono text-[10px] uppercase tracking-[0.28em] disabled:opacity-50 transition-colors">
            {saving ? 'criando…' : 'criar admin'}
          </button>
        </div>
      </form>
    </ModalShell>
  )
}

// ── Modal shell ───────────────────────────────────────────────────────────────

function ModalShell({ children, onClose, title, subtitle, size = 'md' }: {
  children: React.ReactNode; onClose: () => void;
  title: string; subtitle?: string; size?: 'sm' | 'md' | 'lg';
}) {
  // Esc fecha
  useEffect(() => {
    const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }
    window.addEventListener('keydown', h)
    return () => window.removeEventListener('keydown', h)
  }, [onClose])

  const maxW = size === 'sm' ? 'max-w-sm' : size === 'lg' ? 'max-w-2xl' : 'max-w-lg'

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 overflow-y-auto animate-fade-in">
      <div className="absolute inset-0 bg-ink-950/80 backdrop-blur-sm" onClick={onClose} />
      <div className={`relative w-full ${maxW} my-4 bg-ink-900 border border-ink-700 shadow-[0_24px_72px_-12px_rgba(0,0,0,0.6)] animate-fade-up`}>
        {/* corner ticks */}
        <span className="absolute -top-px -left-px w-4 h-4 border-l border-t border-acid-500/70" />
        <span className="absolute -top-px -right-px w-4 h-4 border-r border-t border-acid-500/70" />
        <span className="absolute -bottom-px -left-px w-4 h-4 border-l border-b border-acid-500/70" />
        <span className="absolute -bottom-px -right-px w-4 h-4 border-r border-b border-acid-500/70" />

        <div className="flex items-start justify-between gap-4 p-6 border-b border-ink-800">
          <div>
            <h3 className="font-display text-ink-50 text-2xl leading-none">{title}</h3>
            {subtitle && <p className="mt-1.5 font-mono text-[10px] uppercase tracking-[0.25em] text-ink-500">{subtitle}</p>}
          </div>
          <button onClick={onClose}
            className="text-ink-500 hover:text-acid-500 transition-colors" aria-label="Fechar">
            <X size={18} />
          </button>
        </div>
        {children}
      </div>
    </div>
  )
}

// ── Tenant Card (operator ledger) ─────────────────────────────────────────────

function TenantCard({ tenant, onEdit, onDelete, onCreateAdmin, index }: {
  tenant: Tenant
  onEdit: () => void
  onDelete: () => void
  onCreateAdmin: () => void
  index: number
}) {
  const [stats, setStats] = useState<TenantStats | null>(null)

  useEffect(() => {
    SA.stats(tenant.id).then(setStats).catch(() => {})
  }, [tenant.id])

  const users   = useCountUp(stats?.users ?? 0, 900)
  const revenue = useCountUp(stats?.revenue ?? 0, 900)
  const tickets = useCountUp(stats?.tickets_sold ?? 0, 900)

  const idLabel = `#${String(tenant.id).padStart(3, '0')}`

  return (
    <article
      data-stagger={Math.min(index + 1, 9)}
      className={`brand-strip-host group relative bg-ink-900/60 border border-ink-800 hover:border-ink-600 transition-colors animate-fade-up ${
        tenant.active ? '' : 'opacity-60'
      }`}
    >
      {/* Brand strip */}
      <span className="brand-strip" style={{ background: tenant.primary_color }} />

      <div className="pl-7 pr-5 py-5 space-y-5">
        {/* Header: name + status pill + id */}
        <header className="space-y-1.5">
          <div className="flex items-center gap-3">
            <span className="font-mono text-[10px] uppercase tracking-[0.25em] text-ink-500">{idLabel}</span>
            <span className="h-px flex-1 bg-ink-800 group-hover:bg-ink-700 transition-colors" />
            <span className={`flex items-center gap-1.5 font-mono text-[9px] uppercase tracking-[0.25em] ${
              tenant.active ? 'text-acid-500' : 'text-ink-500'
            }`}>
              <span className={`w-1.5 h-1.5 rounded-full ${tenant.active ? 'bg-acid-500 animate-blink' : 'bg-ink-600'}`} />
              {tenant.active ? 'Ativa' : 'Inativa'}
            </span>
          </div>
          <h3 className="font-display text-ink-50 text-[28px] leading-[1.05] tracking-tight pr-4">
            {tenant.name}
          </h3>
          <p className="font-mono text-[11px] text-ink-400 truncate">
            <span className="text-acid-500">›</span> {tenant.slug}
            {tenant.domain ? <span className="text-ink-600"> · {tenant.domain}</span> : null}
          </p>
        </header>

        {/* Ledger */}
        <div className="border-t border-ink-800 pt-4">
          <div className="grid grid-cols-3 gap-3">
            <Metric label="Usuários" value={String(users)} />
            <Metric label="Receita"  value={fmtBRL(revenue)} />
            <Metric label="Tickets"  value={pad2(tickets)} />
          </div>
          {stats && stats.club_members > 0 && (
            <div className="mt-3 flex items-center gap-2 font-mono text-[10px] uppercase tracking-[0.22em] text-acid-500">
              <span className="w-1.5 h-1.5 bg-acid-500" />
              <span>{stats.club_members} membro{stats.club_members > 1 ? 's' : ''} de clube</span>
            </div>
          )}
        </div>

        {/* Actions: editorial bar */}
        <div className="border-t border-ink-800 pt-4 flex flex-wrap items-center gap-x-5 gap-y-2 font-mono text-[10px] uppercase tracking-[0.22em]">
          <button onClick={onEdit} className="flex items-center gap-1.5 text-ink-300 hover:text-acid-500 transition-colors under-reveal">
            <Edit2 size={11} /> Editar
          </button>
          <button onClick={onCreateAdmin} className="flex items-center gap-1.5 text-ink-300 hover:text-acid-500 transition-colors under-reveal">
            <UserPlus size={11} /> Novo admin
          </button>
          {tenant.app_url && (
            <a href={tenant.app_url} target="_blank" rel="noreferrer"
              className="flex items-center gap-1.5 text-ink-300 hover:text-acid-500 transition-colors under-reveal">
              <ExternalLink size={11} /> Abrir
            </a>
          )}
          <button onClick={onDelete}
            className="ml-auto flex items-center gap-1.5 text-ink-500 hover:text-coral-400 transition-colors under-reveal">
            Remover
          </button>
        </div>
      </div>
    </article>
  )
}

function Metric({ label, value }: { label: string; value: string }) {
  return (
    <div className="space-y-1.5">
      <p className="numeric-display text-ink-50 text-[28px] leading-none truncate">{value}</p>
      <p className="font-mono text-[9px] uppercase tracking-[0.28em] text-ink-500">{label}</p>
    </div>
  )
}

// ── Page header (editorial) ───────────────────────────────────────────────────

function PageHead({ pretitle, title, italicTail, meta, action }: {
  pretitle: string;
  title: string;
  italicTail?: string;
  meta?: React.ReactNode;
  action?: React.ReactNode;
}) {
  return (
    <header className="relative pb-6 border-b border-ink-800">
      <div className="flex flex-wrap items-end justify-between gap-6">
        <div className="min-w-0 flex-1 animate-fade-up">
          <p className="font-mono text-[10px] uppercase tracking-[0.32em] text-acid-500 mb-3">
            <span className="text-ink-500">›</span> {pretitle}
          </p>
          <h1 className="font-display text-ink-50 text-[56px] sm:text-[72px] leading-[0.92] tracking-tight">
            {title}
            {italicTail && <span className="font-display-italic text-acid-500"> {italicTail}</span>}
            <span className="font-display-italic text-acid-500">.</span>
          </h1>
          {meta && (
            <div className="mt-4 font-mono text-[11px] uppercase tracking-[0.2em] text-ink-400">
              {meta}
            </div>
          )}
        </div>
        {action && <div className="shrink-0 animate-fade-up" data-stagger="2">{action}</div>}
      </div>
    </header>
  )
}

// ── Tenants Page ──────────────────────────────────────────────────────────────

function TenantsPage() {
  const [tenants, setTenants]       = useState<Tenant[]>([])
  const [modal, setModal]           = useState<Tenant | null | 'new'>(null)
  const [adminModal, setAdminModal] = useState<Tenant | null>(null)
  const [loading, setLoading]       = useState(true)

  async function load() {
    setLoading(true)
    try { setTenants(await SA.tenants()) }
    catch { setTenants([]) }
    finally { setLoading(false) }
  }

  useEffect(() => { load() }, [])

  async function remove(t: Tenant) {
    if (!confirm(`Desativar "${t.name}"?`)) return
    await SA.remove(t.id)
    load()
  }

  const active   = tenants.filter(t => t.active).length
  const inactive = tenants.filter(t => !t.active).length

  return (
    <div className="space-y-10">
      <PageHead
        pretitle="01 / Empresas"
        title="Tenants"
        italicTail="ativos"
        meta={
          <span>
            <span className="text-acid-500 numeric-display text-base">{pad2(active)}</span>
            <span className="ml-1.5">ativa{active !== 1 ? 's' : ''}</span>
            <span className="mx-3 text-ink-700">·</span>
            <span className="numeric-display text-base text-ink-300">{pad2(inactive)}</span>
            <span className="ml-1.5 text-ink-500">inativa{inactive !== 1 ? 's' : ''}</span>
            <span className="mx-3 text-ink-700">·</span>
            <span className="numeric-display text-base text-ink-300">{pad2(tenants.length)}</span>
            <span className="ml-1.5 text-ink-500">total</span>
          </span>
        }
        action={
          <button
            onClick={() => setModal('new')}
            className="group relative flex items-center gap-2.5 px-5 py-3 border border-acid-500 bg-transparent hover:bg-acid-500 text-acid-500 hover:text-ink-950 transition-colors duration-300"
          >
            <Plus size={14} className="transition-transform group-hover:rotate-90 duration-300" />
            <span className="font-mono text-[10px] uppercase tracking-[0.28em]">Nova empresa</span>
            <span className="absolute -top-px -right-px w-2 h-2 border-r border-t border-current" />
            <span className="absolute -bottom-px -left-px w-2 h-2 border-l border-b border-current" />
          </button>
        }
      />

      {loading ? (
        <LoadingPanel />
      ) : tenants.length === 0 ? (
        <EmptyPanel title="Sem tenants registrados" hint="Cadastre a primeira empresa para inicializar o console." />
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-5">
          {tenants.map((t, i) => (
            <TenantCard
              key={t.id}
              tenant={t}
              index={i}
              onEdit={() => setModal(t)}
              onDelete={() => remove(t)}
              onCreateAdmin={() => setAdminModal(t)}
            />
          ))}
        </div>
      )}

      {modal !== null && (
        <TenantModal
          tenant={modal === 'new' ? null : modal}
          onClose={() => setModal(null)}
          onSaved={load}
        />
      )}
      {adminModal && (
        <CreateAdminModal
          tenantId={adminModal.id}
          tenantName={adminModal.name}
          onClose={() => setAdminModal(null)}
        />
      )}
    </div>
  )
}

// ── Dashboard ─────────────────────────────────────────────────────────────────

function DashboardPage() {
  const [tenants, setTenants] = useState<Tenant[]>([])
  const [loading, setLoading] = useState(true)
  const navigate = useNavigate()

  useEffect(() => {
    SA.tenants()
      .then(t => setTenants(t))
      .catch(() => setTenants([]))
      .finally(() => setLoading(false))
  }, [])

  const total    = tenants.length
  const ativas   = tenants.filter(t => t.active).length
  const inativas = total - ativas
  const dominios = tenants.filter(t => !!t.domain).length

  const cTotal    = useCountUp(total, 900)
  const cAtivas   = useCountUp(ativas, 900)
  const cInativas = useCountUp(inativas, 900)
  const cDominios = useCountUp(dominios, 900)

  const kpis = [
    { label: 'Tenants',  value: pad2(cTotal),    note: 'registrados' },
    { label: 'Ativas',   value: pad2(cAtivas),   note: 'em produção',  acid: true },
    { label: 'Inativas', value: pad2(cInativas), note: 'desativadas' },
    { label: 'Domínios', value: pad2(cDominios), note: 'configurados' },
  ]

  return (
    <div className="space-y-10">
      <PageHead
        pretitle="00 / Visão global"
        title="Console"
        italicTail="overview"
        meta={
          <span>
            <span>todas as empresas da plataforma</span>
            <span className="mx-3 text-ink-700">·</span>
            <span className="text-acid-500">tempo real</span>
          </span>
        }
      />

      {/* KPI bar */}
      <section className="grid grid-cols-2 lg:grid-cols-4">
        {kpis.map((k, i) => (
          <div
            key={k.label}
            data-stagger={i + 1}
            className="relative animate-fade-up px-5 py-7 border border-ink-800 -mr-px -mb-px bg-ink-900/40 hover:bg-ink-900/70 transition-colors"
          >
            <div className="flex items-baseline justify-between mb-3">
              <span className="font-mono text-[10px] uppercase tracking-[0.28em] text-ink-400">{k.label}</span>
              <span className={`font-mono text-[9px] uppercase tracking-[0.22em] ${k.acid ? 'text-acid-500' : 'text-ink-600'}`}>
                /{String(i).padStart(2, '0')}
              </span>
            </div>
            <p className={`numeric-display ${k.acid ? 'text-acid-500' : 'text-ink-50'} text-[68px] leading-[0.85]`}>{k.value}</p>
            <p className="mt-3 font-mono text-[10px] uppercase tracking-[0.22em] text-ink-500">{k.note}</p>
          </div>
        ))}
      </section>

      {/* Tenant index — list, not grid */}
      <section>
        <div className="flex items-center gap-3 mb-4">
          <span className="font-mono text-[10px] uppercase tracking-[0.32em] text-ink-400">↳ Index</span>
          <span className="h-px flex-1 bg-ink-800" />
          <span className="font-mono text-[10px] uppercase tracking-[0.22em] text-ink-500">{pad2(ativas)} entradas</span>
        </div>

        {loading ? (
          <LoadingPanel />
        ) : ativas === 0 ? (
          <EmptyPanel title="Nada para mostrar" hint="Quando houver tenants ativos, aparecem aqui." />
        ) : (
          <ul className="border border-ink-800 divide-y divide-ink-800">
            {tenants.filter(t => t.active).map((t, i) => (
              <li key={t.id} data-stagger={Math.min(i + 1, 9)} className="animate-slide-right">
                <button
                  onClick={() => navigate('/tenants')}
                  className="group w-full flex items-center gap-4 px-4 sm:px-6 py-5 hover:bg-ink-900/60 transition-colors text-left"
                >
                  <span className="numeric-display text-ink-500 group-hover:text-acid-500 text-2xl tabular w-10 transition-colors">
                    {pad2(i + 1)}
                  </span>
                  <span className="w-1 h-10 shrink-0 transition-all duration-300 group-hover:h-12" style={{ background: t.primary_color }} />
                  <div className="min-w-0 flex-1">
                    <h4 className="font-display text-ink-50 group-hover:text-acid-500 transition-colors text-xl leading-none truncate">{t.name}</h4>
                    <p className="mt-1.5 font-mono text-[11px] text-ink-500 truncate">
                      {t.slug}{t.domain ? ` · ${t.domain}` : ''}
                    </p>
                  </div>
                  <span className="hidden sm:inline font-mono text-[10px] uppercase tracking-[0.25em] text-ink-500 group-hover:text-acid-500 transition-colors">
                    visitar
                  </span>
                  <ChevronRight size={16} className="text-ink-600 group-hover:text-acid-500 group-hover:translate-x-1 transition-all" />
                </button>
              </li>
            ))}
          </ul>
        )}
      </section>
    </div>
  )
}

// ── Loading / Empty ───────────────────────────────────────────────────────────

function LoadingPanel() {
  return (
    <div className="border border-ink-800 py-24 flex flex-col items-center justify-center gap-3">
      <div className="flex gap-1.5">
        <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '0ms' }} />
        <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '200ms' }} />
        <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '400ms' }} />
      </div>
      <span className="font-mono text-[10px] uppercase tracking-[0.3em] text-ink-500">carregando</span>
    </div>
  )
}

function EmptyPanel({ title, hint }: { title: string; hint?: string }) {
  return (
    <div className="border border-dashed border-ink-700 py-16 px-6 text-center">
      <p className="font-display text-ink-300 text-2xl">{title}</p>
      {hint && <p className="mt-2 font-mono text-[11px] uppercase tracking-[0.22em] text-ink-500">↳ {hint}</p>}
    </div>
  )
}

// ── Sidebar (operator rail) ───────────────────────────────────────────────────

function Sidebar({ onLogout, isOpen, onClose }: { onLogout: () => void; isOpen: boolean; onClose: () => void }) {
  const path = useLocation().pathname

  const items = [
    { icon: LayoutDashboard, label: 'Console',   href: '/',         tag: '00' },
    { icon: Building2,       label: 'Tenants',   href: '/tenants',  tag: '01' },
  ]

  return (
    <>
      {isOpen && (
        <div className="fixed inset-0 bg-ink-950/80 z-30 md:hidden animate-fade-in" onClick={onClose} />
      )}
      <aside
        className={`
          fixed md:sticky top-0 left-0 z-40
          w-72 md:w-[68px] hover:md:w-[212px]
          h-screen flex flex-col
          bg-ink-900 md:bg-ink-950 border-r border-ink-800
          transition-[transform,width] duration-400 ease-[cubic-bezier(0.16,1,0.3,1)]
          group/rail
          ${isOpen ? 'translate-x-0' : '-translate-x-full md:translate-x-0'}
        `}
      >
        {/* Brand */}
        <div className="px-4 py-5 border-b border-ink-800 flex items-center gap-3 md:overflow-hidden">
          <div className="relative shrink-0 w-9 h-9 bg-ink-950 border border-acid-500 flex items-center justify-center">
            <span className="font-display-italic text-acid-500 text-xl leading-none">α</span>
            <span className="absolute -top-px -left-px w-1.5 h-1.5 border-l border-t border-acid-500" />
            <span className="absolute -bottom-px -right-px w-1.5 h-1.5 border-r border-b border-acid-500" />
          </div>
          <div className="min-w-0 md:opacity-0 md:group-hover/rail:opacity-100 transition-opacity duration-300 delay-75">
            <p className="font-mono text-[9px] uppercase tracking-[0.32em] text-ink-500 leading-tight">Alemão</p>
            <p className="font-display text-ink-50 text-base leading-none mt-0.5 whitespace-nowrap">
              super<span className="font-display-italic text-acid-500">.</span>
            </p>
          </div>
          <button onClick={onClose} className="md:hidden ml-auto text-ink-500 hover:text-acid-500 transition-colors">
            <X size={18} />
          </button>
        </div>

        {/* Nav */}
        <nav className="flex-1 py-4 px-2 space-y-px md:overflow-hidden">
          {items.map(({ icon: Icon, label, href, tag }) => {
            const active = path === href
            return (
              <Link
                key={href}
                to={href}
                onClick={onClose}
                className={`
                  group/item relative flex items-center gap-3 px-3 py-3
                  font-mono text-[10px] uppercase tracking-[0.28em]
                  transition-colors
                  ${active ? 'text-acid-500 bg-ink-900' : 'text-ink-400 hover:text-ink-100 hover:bg-ink-900/50'}
                `}
              >
                {active && <span className="absolute left-0 top-2 bottom-2 w-0.5 bg-acid-500" />}
                <Icon size={16} className="shrink-0" />
                <span className="md:opacity-0 md:group-hover/rail:opacity-100 transition-opacity duration-300 delay-75 truncate flex-1">{label}</span>
                <span className={`md:opacity-0 md:group-hover/rail:opacity-100 transition-opacity duration-300 delay-75 text-[9px] tracking-[0.22em] ${active ? 'text-acid-500/80' : 'text-ink-600'}`}>
                  {tag}
                </span>
              </Link>
            )
          })}
        </nav>

        {/* Footer signature */}
        <div className="px-3 py-4 border-t border-ink-800 space-y-1">
          <button
            onClick={onLogout}
            className="group/lo w-full flex items-center gap-3 px-3 py-2.5 text-ink-400 hover:text-coral-400 hover:bg-coral-500/5 transition-colors font-mono text-[10px] uppercase tracking-[0.28em]"
          >
            <LogOut size={15} className="shrink-0" />
            <span className="md:opacity-0 md:group-hover/rail:opacity-100 transition-opacity duration-300 delay-75 truncate">
              Encerrar sessão
            </span>
          </button>
          <p className="hidden md:block px-3 font-mono text-[8px] uppercase tracking-[0.32em] text-ink-700 md:opacity-0 md:group-hover/rail:opacity-100 transition-opacity duration-300 delay-150 leading-tight">
            v1.0 · build 2026<br/>
            super-admin@nuvem
          </p>
        </div>
      </aside>
    </>
  )
}

// ── App shell ─────────────────────────────────────────────────────────────────

type AuthState = 'checking' | 'ok' | 'login'

function AppContent({ auth, setAuth }: { auth: AuthState; setAuth: (s: AuthState) => void }) {
  const navigate = useNavigate()
  const location = useLocation()
  const [sidebarOpen, setSidebarOpen] = useState(false)

  useEffect(() => { setSidebarOpen(false) }, [location.pathname])

  if (auth === 'login') return <LoginPage onLogin={() => { setAuth('ok'); navigate('/') }} />

  async function logout() {
    await SA.logout().catch(() => {})
    setAuth('login')
  }

  return (
    <div className="relative flex min-h-screen bg-ink-950 text-ink-100 noise">
      <Sidebar onLogout={logout} isOpen={sidebarOpen} onClose={() => setSidebarOpen(false)} />

      <div className="relative flex-1 flex flex-col min-w-0">
        <TelemetryStrip />

        {/* Mobile header */}
        <header className="md:hidden flex items-center gap-4 px-4 h-12 bg-ink-950 border-b border-ink-800 sticky top-7 z-20">
          <button onClick={() => setSidebarOpen(true)} className="text-ink-300 hover:text-acid-500 transition-colors">
            <Menu size={20} />
          </button>
          <span className="font-display text-ink-50 text-lg leading-none">
            super<span className="font-display-italic text-acid-500">.</span>
          </span>
        </header>

        <main className="relative flex-1 overflow-x-hidden">
          {/* Background grid + scanline */}
          <div className="absolute inset-0 bg-grid bg-grid-fade pointer-events-none" />

          <div className="relative px-4 sm:px-8 lg:px-14 py-10 lg:py-14">
            <div className="max-w-[1280px] mx-auto">
              <Routes>
                <Route path="/"        element={<DashboardPage />} />
                <Route path="/tenants" element={<TenantsPage />} />
              </Routes>
            </div>

            <footer className="max-w-[1280px] mx-auto mt-24 pt-6 border-t border-ink-800 flex flex-wrap items-center gap-x-4 gap-y-2 font-mono text-[10px] uppercase tracking-[0.25em] text-ink-500">
              <span><span className="text-acid-500">▣</span> Operator console</span>
              <span className="text-ink-700">/</span>
              <span>Alemão · Nuvem SaaS</span>
              <span className="text-ink-700">/</span>
              <span>Multi-tenant</span>
              <span className="ml-auto text-ink-600">© 2026</span>
            </footer>
          </div>
        </main>
      </div>
    </div>
  )
}

export default function App() {
  const [auth, setAuth] = useState<AuthState>('checking')

  useEffect(() => {
    SA.me()
      .then(() => setAuth('ok'))
      .catch(() => setAuth('login'))

    const handler = () => setAuth('login')
    window.addEventListener('sa:logout', handler)
    return () => window.removeEventListener('sa:logout', handler)
  }, [])

  if (auth === 'checking') {
    return (
      <div className="min-h-screen bg-ink-950 flex items-center justify-center">
        <div className="flex flex-col items-center gap-4">
          <div className="flex gap-1.5">
            <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '0ms' }} />
            <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '200ms' }} />
            <span className="w-1.5 h-1.5 bg-acid-500 animate-blink" style={{ animationDelay: '400ms' }} />
          </div>
          <span className="font-mono text-[10px] uppercase tracking-[0.3em] text-ink-500">verificando sessão</span>
        </div>
      </div>
    )
  }

  return (
    <Router basename="/superadmin">
      <AppContent auth={auth} setAuth={setAuth} />
    </Router>
  )
}
