// app/[locale]/(app)/portfolio/page.tsx
"use client"

import * as React from "react"
import { useLocale, useTranslations } from "next-intl"
import {
  listPortfolios,
  createPortfolio,
  updatePortfolio,
  deletePortfolio,
  type Portfolio,
  type PortfolioPriority,
} from "@/src/lib/api/portfolios"
import { api } from "@/src/lib/api/client"
import { CURRENCIES, type Currency } from "@/src/lib/constants/currencies"
import Link from "next/link"
import {
  Search, Plus, Pencil, Trash2, X, Save, RefreshCw, Filter,
  Layers, ShieldCheck, AlertTriangle, UserRound, Coins, Check,
  ChevronDown, TrendingUp, FolderOpen, BarChart3, Loader2,
  ArrowUpRight,
} from "lucide-react"

// ── Palette ────────────────────────────────────────────────────────────────────
const NAVY  = "#1a3578"
const NAVY2 = "#2655b0"
const TEAL  = "#4dba96"

function cx(...c: Array<string | false | null | undefined>) {
  return c.filter(Boolean).join(" ")
}

function fmtDate(d?: string | null) {
  if (!d) return "—"
  const dt = new Date(d)
  if (Number.isNaN(dt.getTime())) return d
  return dt.toLocaleDateString("fr-FR", { day: "2-digit", month: "short", year: "numeric" })
}

function fmtMoney(v?: string | number | null, currency?: string | null) {
  if (v === null || v === undefined || v === "" || v === "0" || v === 0) return "—"
  const num = typeof v === "string" ? parseFloat(v) : v
  if (isNaN(num)) return String(v)
  return new Intl.NumberFormat("fr-FR", { maximumFractionDigits: 0 }).format(num) +
    (currency ? ` ${currency}` : "")
}

// ── Priority helpers ───────────────────────────────────────────────────────────
function PriorityBadge({ v, label }: { v: PortfolioPriority; label: string }) {
  const cls = {
    low:    "bg-slate-100 text-slate-600 border-slate-200",
    medium: "bg-sky-50 text-sky-700 border-sky-200",
    high:   "bg-orange-50 text-orange-700 border-orange-200",
  }[v] ?? "bg-sky-50 text-sky-700 border-sky-200"
  return (
    <span className={cx("inline-flex items-center rounded-full px-2.5 py-0.5 text-[11px] font-semibold border", cls)}>
      {label}
    </span>
  )
}

function StatusBadge({ active, labels }: { active: boolean; labels: { active: string; inactive: string } }) {
  return active ? (
    <span className="inline-flex items-center rounded-full px-2.5 py-0.5 text-[11px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200">
      {labels.active}
    </span>
  ) : (
    <span className="inline-flex items-center rounded-full px-2.5 py-0.5 text-[11px] font-semibold bg-slate-100 text-slate-500 border border-slate-200">
      {labels.inactive}
    </span>
  )
}

// ── Searchable Select ──────────────────────────────────────────────────────────
type SelectOption = { value: string; label: string }

function SearchableSelect({ value, onChange, options, placeholder, disabled, icon, noResults }: {
  value: string
  onChange: (v: string) => void
  options: SelectOption[]
  placeholder: string
  disabled?: boolean
  icon?: React.ReactNode
  noResults?: string
}) {
  const [open, setOpen] = React.useState(false)
  const [q, setQ] = React.useState("")
  const ref = React.useRef<HTMLDivElement | null>(null)

  React.useEffect(() => {
    function onDoc(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)
    }
    document.addEventListener("mousedown", onDoc)
    return () => document.removeEventListener("mousedown", onDoc)
  }, [])

  const current = options.find(o => o.value === value)
  const filtered = q ? options.filter(o => o.label.toLowerCase().includes(q.toLowerCase())) : options

  return (
    <div className="relative" ref={ref}>
      <button
        type="button"
        disabled={disabled}
        onClick={() => !disabled && setOpen(s => !s)}
        className="w-full rounded-xl border border-slate-200 px-3 py-2 text-sm bg-white inline-flex items-center justify-between gap-2 hover:border-slate-300 transition disabled:opacity-50 disabled:cursor-not-allowed"
      >
        <span className="inline-flex items-center gap-2 min-w-0">
          {icon && <span className="shrink-0 text-slate-400">{icon}</span>}
          <span className={cx("truncate text-left", !current && "text-slate-400")}>
            {current ? current.label : placeholder}
          </span>
        </span>
        <ChevronDown className="h-3.5 w-3.5 text-slate-400 shrink-0" />
      </button>

      {open && !disabled && (
        <div className="absolute z-[80] mt-1 w-full min-w-[220px] rounded-2xl border border-slate-200 bg-white shadow-xl overflow-hidden">
          <div className="p-2 border-b border-slate-100">
            <div className="flex items-center gap-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-1.5">
              <Search className="h-3.5 w-3.5 text-slate-400" />
              <input
                className="flex-1 bg-transparent outline-none text-sm"
                placeholder={placeholder}
                value={q}
                onChange={e => setQ(e.target.value)}
                autoFocus
              />
              {q && (
                <button type="button" onClick={() => setQ("")}>
                  <X className="h-3.5 w-3.5 text-slate-400 hover:text-slate-600" />
                </button>
              )}
            </div>
          </div>
          <div className="max-h-56 overflow-auto">
            {filtered.length === 0 ? (
              <div className="px-3 py-4 text-sm text-slate-400 text-center">{noResults ?? placeholder}</div>
            ) : filtered.map(o => (
              <button key={o.value} type="button"
                className="w-full text-left px-3 py-2 text-sm hover:bg-slate-50 inline-flex items-center justify-between gap-2 transition"
                onClick={() => { onChange(o.value); setOpen(false); setQ("") }}
              >
                <span className="truncate">{o.label}</span>
                {o.value === value && <Check className="h-3.5 w-3.5 shrink-0" style={{ color: TEAL }} />}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  )
}

// ── Types ──────────────────────────────────────────────────────────────────────
type TenantUser = {
  id: number; username: string
  first_name?: string | null; last_name?: string | null; email?: string | null
}

type FormState = {
  id?: number; name: string; code: string; category: string
  priority: PortfolioPriority; default_currency: string
  description: string; internal_notes: string; owner: string; is_active: boolean
}

const defaultForm: FormState = {
  name: "", code: "", category: "", priority: "medium",
  default_currency: "", description: "", internal_notes: "", owner: "", is_active: true,
}

// ── Page ───────────────────────────────────────────────────────────────────────
export default function PortfolioPage() {
  const locale = useLocale()
  const t  = useTranslations("portfolios")
  const tc = useTranslations("common")

  const [items, setItems]       = React.useState<Portfolio[]>([])
  const [users, setUsers]       = React.useState<TenantUser[]>([])
  const [loading, setLoading]   = React.useState(true)
  const [saving, setSaving]     = React.useState(false)
  const [error, setError]       = React.useState<string | null>(null)

  // Filters
  const [q, setQ]                         = React.useState("")
  const [filterActive, setFilterActive]   = React.useState<"all" | "active" | "inactive">("all")
  const [filterPriority, setFilterPriority] = React.useState<"" | PortfolioPriority>("")
  const [filterCurrency, setFilterCurrency] = React.useState("")
  const [filterOwner, setFilterOwner]     = React.useState("")
  const [showFilters, setShowFilters]     = React.useState(false)

  // Modal
  const [open, setOpen]   = React.useState(false)
  const [form, setForm]   = React.useState<FormState>(defaultForm)

  // Options
  const currencyOptions = React.useMemo(() =>
    CURRENCIES.map(c => ({
      value: c.code,
      label: locale === "fr" ? `${c.code} — ${c.fr}` : `${c.code} — ${c.en}`,
    })), [locale])

  const ownerOptions = React.useMemo(() =>
    users.map(u => {
      const name = `${u.first_name ?? ""} ${u.last_name ?? ""}`.trim()
      return { value: String(u.id), label: name ? `${name} (@${u.username})` : `@${u.username}` }
    }), [users])

  function priorityLabel(v: PortfolioPriority) {
    return t(`priority.${v}` as any) as string
  }

  // ── Data loading ─────────────────────────────────────────────────────────────
  async function refresh() {
    setLoading(true); setError(null)
    try {
      const data = await listPortfolios({
        q: q.trim() || undefined,
        is_active: filterActive === "all" ? undefined : filterActive === "active",
        priority: filterPriority || undefined,
      })
      const filtered = data.filter(p => {
        if (filterCurrency && (p.default_currency || "").toUpperCase() !== filterCurrency.toUpperCase()) return false
        if (filterOwner && String(p.owner ?? "") !== filterOwner) return false
        return true
      })
      setItems(filtered)
    } catch (e: any) {
      setError(e?.message ?? "Erreur de chargement")
    } finally {
      setLoading(false)
    }
  }

  async function loadUsers() {
    try { setUsers(await api.request<TenantUser[]>("/tenant/users/")) }
    catch { setUsers([]) }
  }

  React.useEffect(() => {
    Promise.all([refresh(), loadUsers()])
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // ── KPIs ──────────────────────────────────────────────────────────────────────
  // helpers pour les noms de champs doubles (backend peut envoyer l'un ou l'autre)
  function pCasesTotal(p: Portfolio): number { return Number(p.cases_total ?? p.cases_count ?? 0) }
  function pCasesOpen(p: Portfolio): number  { return Number(p.cases_open ?? p.open_cases_count ?? 0) }
  function pCasesOverdue(p: Portfolio): number { return Number(p.cases_overdue ?? p.overdue_cases_count ?? 0) }

  const kpis = React.useMemo(() => {
    const active    = items.filter(p => p.is_active).length
    const highPrio  = items.filter(p => p.priority === "high").length
    const totalBalance = items.reduce((s, p) => {
      const v = parseFloat(String(p.balance_total ?? 0))
      return s + (isNaN(v) ? 0 : v)
    }, 0)
    const totalCases = items.reduce((s, p) => s + pCasesTotal(p), 0)
    return { total: items.length, active, highPrio, totalBalance, totalCases }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [items])

  // ── CRUD ──────────────────────────────────────────────────────────────────────
  function startCreate() { setError(null); setForm(defaultForm); setOpen(true) }

  function startEdit(p: Portfolio) {
    setError(null)
    setForm({
      id: p.id, name: p.name ?? "", code: p.code ?? "", category: p.category ?? "",
      priority: p.priority ?? "medium", default_currency: p.default_currency ?? "",
      description: p.description ?? "", internal_notes: p.internal_notes ?? "",
      owner: p.owner ? String(p.owner) : "", is_active: !!p.is_active,
    })
    setOpen(true)
  }

  async function onSave() {
    setSaving(true); setError(null)
    try {
      const payload = {
        name: form.name.trim(),
        code: form.code.trim() || null,
        category: form.category.trim() || null,
        priority: form.priority,
        default_currency: form.default_currency.trim().toUpperCase() || null,
        description: form.description.trim() || null,
        internal_notes: form.internal_notes.trim() || null,
        owner: form.owner.trim() ? Number(form.owner.trim()) : null,
        is_active: form.is_active,
      }
      if (!payload.name) { setError(t("name_required")); return }
      if (form.id) await updatePortfolio(form.id, payload)
      else await createPortfolio(payload)
      setOpen(false)
      await refresh()
    } catch (e: any) {
      setError(e?.message ?? "Erreur")
    } finally {
      setSaving(false)
    }
  }

  async function onDelete(id: number) {
    if (!window.confirm(t("confirm_delete"))) return
    setSaving(true); setError(null)
    try { await deletePortfolio(id); await refresh() }
    catch (e: any) { setError(e?.message ?? "Erreur") }
    finally { setSaving(false) }
  }

  const activeFiltersCount = [filterActive !== "all", filterPriority !== "", filterCurrency !== "", filterOwner !== ""].filter(Boolean).length

  // ── Render ────────────────────────────────────────────────────────────────────
  return (
    <div className="space-y-5">

      {/* ── Hero header ─────────────────────────────────────────────────────── */}
      <div
        className="relative overflow-hidden rounded-2xl px-6 py-5 text-white"
        style={{ background: `linear-gradient(135deg, ${NAVY} 0%, ${NAVY2} 100%)` }}
      >
        <div className="pointer-events-none absolute -top-10 -right-10 h-40 w-40 rounded-full opacity-[0.07]"
          style={{ background: `radial-gradient(circle, ${TEAL}, transparent 70%)` }} />
        <div className="relative flex items-center justify-between gap-4 flex-wrap">
          <div>
            <h1 className="text-xl font-bold tracking-tight">{t("title")}</h1>
            <p className="text-sm text-white/60 mt-0.5">{t("header_subtitle")}</p>
          </div>
          <div className="flex items-center gap-2">
            <button onClick={() => refresh()}
              className="rounded-xl border border-white/20 p-2 hover:bg-white/10 transition"
              disabled={loading}>
              <RefreshCw className={cx("h-4 w-4", loading && "animate-spin")} />
            </button>
            <button onClick={startCreate}
              className="rounded-xl px-4 py-2 text-sm font-semibold inline-flex items-center gap-2 transition hover:opacity-90"
              style={{ background: TEAL }}>
              <Plus className="h-4 w-4" />
              {t("new")}
            </button>
          </div>
        </div>
      </div>

      {/* ── KPIs ────────────────────────────────────────────────────────────── */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        {[
          { label: t("kpi.total"),        value: kpis.total,       icon: FolderOpen,     color: NAVY,     bg: "rgba(26,53,120,.08)" },
          { label: t("kpi.active"),       value: kpis.active,      icon: ShieldCheck,    color: "#10b981", bg: "rgba(16,185,129,.08)" },
          { label: t("kpi.high_priority"),value: kpis.highPrio,    icon: AlertTriangle,  color: "#f97316", bg: "rgba(249,115,22,.08)" },
          { label: t("kpi.total_cases"),  value: kpis.totalCases,  icon: Layers,         color: TEAL,     bg: "rgba(77,186,150,.10)" },
        ].map(({ label, value, icon: Icon, color, bg }) => (
          <div key={label} className="rounded-2xl border border-slate-200 bg-white p-4 flex items-center gap-3 shadow-sm">
            <div className="rounded-xl p-2.5 shrink-0" style={{ background: bg }}>
              <Icon className="h-4 w-4" style={{ color }} />
            </div>
            <div>
              <div className="text-xl font-bold text-slate-900 leading-none">{value}</div>
              <div className="text-[11px] font-medium text-slate-400 uppercase tracking-wide mt-0.5">{label}</div>
            </div>
          </div>
        ))}
      </div>

      {/* ── Filters ─────────────────────────────────────────────────────────── */}
      <div className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <div className="flex items-center gap-3 px-4 py-3">
          {/* Search */}
          <div className="flex-1 flex items-center gap-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2">
            <Search className="h-4 w-4 text-slate-400 shrink-0" />
            <input
              className="flex-1 bg-transparent outline-none text-sm"
              placeholder={t("search_placeholder")}
              value={q}
              onChange={e => setQ(e.target.value)}
              onKeyDown={e => e.key === "Enter" && refresh()}
            />
            {q && <button onClick={() => setQ("")}><X className="h-3.5 w-3.5 text-slate-400" /></button>}
          </div>

          {/* Active/Inactive quick filter */}
          <div className="flex rounded-xl border border-slate-200 overflow-hidden text-xs shrink-0">
            {(["all", "active", "inactive"] as const).map(v => (
              <button key={v} onClick={() => setFilterActive(v)}
                className="px-3 py-2 transition"
                style={filterActive === v ? { background: NAVY, color: "#fff" } : { color: "#64748b" }}>
                {t(`filters.${v}` as any)}
              </button>
            ))}
          </div>

          {/* Filter toggle */}
          <button
            onClick={() => setShowFilters(s => !s)}
            className={cx(
              "rounded-xl border px-3 py-2 text-xs font-medium inline-flex items-center gap-1.5 transition",
              showFilters ? "bg-navy text-white border-transparent" : "bg-white border-slate-200 text-slate-600 hover:bg-slate-50"
            )}
            style={showFilters ? { background: NAVY } : {}}
          >
            <Filter className="h-3.5 w-3.5" />
            {t("filters.filters_btn")}
            {activeFiltersCount > 0 && (
              <span className="ml-0.5 rounded-full px-1.5 py-0.5 text-[10px] font-bold"
                style={{ background: TEAL, color: "#fff" }}>
                {activeFiltersCount}
              </span>
            )}
          </button>

          <button onClick={() => refresh()} disabled={loading}
            className="rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs font-medium text-slate-600 hover:bg-slate-50 transition disabled:opacity-50 inline-flex items-center gap-1.5">
            {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Search className="h-3.5 w-3.5" />}
            {t("filters.search_btn")}
          </button>

          <div className="text-xs text-slate-400 shrink-0">{items.length}</div>
        </div>

        {/* Expanded filter panel */}
        {showFilters && (
          <div className="border-t border-slate-100 px-4 py-3 grid grid-cols-1 sm:grid-cols-3 gap-3">
            <div>
              <label className="block text-[11px] font-medium text-slate-500 mb-1 uppercase tracking-wide">{t("filters.label_priority")}</label>
              <select
                className="w-full rounded-xl border border-slate-200 px-3 py-2 text-sm bg-white"
                value={filterPriority}
                onChange={e => setFilterPriority(e.target.value as any)}
              >
                <option value="">{t("filters.all_priorities")}</option>
                <option value="low">{t("priority.low")}</option>
                <option value="medium">{t("priority.medium")}</option>
                <option value="high">{t("priority.high")}</option>
              </select>
            </div>
            <div>
              <label className="block text-[11px] font-medium text-slate-500 mb-1 uppercase tracking-wide">{t("filters.label_currency")}</label>
              <SearchableSelect
                value={filterCurrency}
                onChange={v => setFilterCurrency(v)}
                options={[{ value: "", label: t("filters.all_currencies") }, ...currencyOptions]}
                placeholder={t("filters.label_currency")}
                noResults={t("no_results")}
                icon={<Coins className="h-3.5 w-3.5" />}
              />
            </div>
            <div>
              <label className="block text-[11px] font-medium text-slate-500 mb-1 uppercase tracking-wide">{t("filters.label_owner")}</label>
              <SearchableSelect
                value={filterOwner}
                onChange={v => setFilterOwner(v)}
                options={[{ value: "", label: t("filters.all_owners") }, ...ownerOptions]}
                placeholder={t("filters.label_owner")}
                noResults={t("no_results")}
                icon={<UserRound className="h-3.5 w-3.5" />}
              />
            </div>
            <div className="sm:col-span-3 flex justify-end">
              <button
                onClick={() => { setFilterPriority(""); setFilterCurrency(""); setFilterOwner(""); setTimeout(refresh, 0) }}
                className="text-xs text-slate-500 hover:text-red-500 inline-flex items-center gap-1 transition"
              >
                <X className="h-3 w-3" /> {t("filters.reset")}
              </button>
            </div>
          </div>
        )}
      </div>

      {/* Error */}
      {error && !open && (
        <div className="rounded-2xl border border-red-100 bg-red-50 px-4 py-3 text-sm text-red-700">{error}</div>
      )}

      {/* ── Table ───────────────────────────────────────────────────────────── */}
      <div className="rounded-2xl border border-slate-200 bg-white shadow-sm overflow-hidden">
        {loading ? (
          <div className="divide-y divide-slate-100">
            {[1,2,3,4].map(i => (
              <div key={i} className="p-4 flex items-center gap-4 animate-pulse">
                <div className="h-10 w-10 rounded-xl bg-slate-100 shrink-0" />
                <div className="flex-1 space-y-2">
                  <div className="h-3.5 bg-slate-100 rounded w-1/4" />
                  <div className="h-3 bg-slate-100 rounded w-1/2" />
                </div>
                <div className="h-6 bg-slate-100 rounded-full w-16" />
              </div>
            ))}
          </div>
        ) : items.length === 0 ? (
          <div className="flex flex-col items-center gap-3 py-16 text-slate-400">
            <FolderOpen className="h-10 w-10 opacity-30" />
            <p className="text-sm">{t("empty_create")}</p>
            <button onClick={startCreate}
              className="mt-1 rounded-xl px-4 py-2 text-sm font-semibold text-white"
              style={{ background: TEAL }}>
              <Plus className="h-4 w-4 inline mr-1.5" />{t("new")}
            </button>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-slate-100 text-left">
                  {[t("table.portfolio_col"), t("table.status_col"), t("table.priority"), t("table.cases"), t("table.balance_col"), t("table.owner_col"), t("table.created_col"), ""].map(h => (
                    <th key={h} className="px-4 py-3 text-[11px] font-semibold text-slate-400 uppercase tracking-wide whitespace-nowrap">
                      {h}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-50">
                {items.map(p => {
                  const openRatio = pCasesTotal(p) ? (pCasesOpen(p) ?? 0) / pCasesTotal(p) : 0
                  return (
                    <tr key={p.id} className="hover:bg-slate-50/60 transition group">
                      {/* Name + meta */}
                      <td className="px-4 py-3.5 max-w-xs">
                        <div className="flex items-start gap-3">
                          <div className="h-9 w-9 rounded-xl flex items-center justify-center text-xs font-bold text-white shrink-0"
                            style={{ background: `linear-gradient(135deg, ${NAVY} 0%, ${NAVY2} 100%)` }}>
                            {(p.name ?? "P").charAt(0).toUpperCase()}
                          </div>
                          <div className="min-w-0">
                            <div className="font-semibold text-slate-800 truncate">{p.name}</div>
                            <div className="flex items-center gap-2 mt-0.5 flex-wrap">
                              {p.code && (
                                <span className="text-[11px] font-mono bg-slate-100 text-slate-500 px-1.5 py-0.5 rounded">
                                  {p.code}
                                </span>
                              )}
                              {p.category && (
                                <span className="text-[11px] text-slate-400">{p.category}</span>
                              )}
                              {p.default_currency && (
                                <span className="text-[11px] text-slate-400">{p.default_currency}</span>
                              )}
                            </div>
                            {p.description && (
                              <div className="text-xs text-slate-400 mt-1 truncate max-w-[260px]">{p.description}</div>
                            )}
                          </div>
                        </div>
                      </td>

                      {/* Status */}
                      <td className="px-4 py-3.5 whitespace-nowrap">
                        <StatusBadge active={!!p.is_active} labels={{ active: t("active"), inactive: t("inactive") }} />
                      </td>

                      {/* Priority */}
                      <td className="px-4 py-3.5 whitespace-nowrap">
                        <PriorityBadge v={p.priority ?? "medium"} label={t(`priority.${p.priority ?? "medium"}` as any)} />
                      </td>

                      {/* Cases progress */}
                      <td className="px-4 py-3.5 min-w-[130px]">
                        <div className="space-y-1">
                          <div className="flex items-center justify-between text-xs text-slate-500 gap-3">
                            <span className="flex items-center gap-1">
                              <Layers className="h-3 w-3" style={{ color: TEAL }} />
                              {pCasesTotal(p) ?? 0} total
                            </span>
                            {(pCasesOverdue(p) ?? 0) > 0 && (
                              <span className="text-orange-500 font-medium">{pCasesOverdue(p)} retard</span>
                            )}
                          </div>
                          {(pCasesTotal(p) ?? 0) > 0 && (
                            <div className="h-1.5 w-full bg-slate-100 rounded-full overflow-hidden">
                              <div className="h-full rounded-full transition-all"
                                style={{ width: `${Math.round(openRatio * 100)}%`, background: TEAL }} />
                            </div>
                          )}
                        </div>
                      </td>

                      {/* Balance */}
                      <td className="px-4 py-3.5 whitespace-nowrap">
                        <div className="font-semibold text-slate-800 text-sm">
                          {fmtMoney(p.balance_total, p.default_currency)}
                        </div>
                      </td>

                      {/* Owner */}
                      <td className="px-4 py-3.5 whitespace-nowrap">
                        {p.owner_username ? (
                          <div className="flex items-center gap-1.5">
                            <div className="h-6 w-6 rounded-full bg-slate-200 flex items-center justify-center text-[10px] font-bold text-slate-500">
                              {p.owner_username.charAt(0).toUpperCase()}
                            </div>
                            <span className="text-xs text-slate-600">@{p.owner_username}</span>
                          </div>
                        ) : (
                          <span className="text-slate-300 text-xs">—</span>
                        )}
                      </td>

                      {/* Date */}
                      <td className="px-4 py-3.5 whitespace-nowrap text-xs text-slate-400">
                        {fmtDate(p.created_at)}
                      </td>

                      {/* Actions */}
                      <td className="px-4 py-3.5">
                        <div className="flex items-center gap-1.5">
                          <Link
                            href={`/${locale}/portfolio/${p.id}`}
                            className="h-8 px-2.5 rounded-xl border border-slate-200 bg-white hover:bg-slate-50 flex items-center gap-1.5 text-xs font-medium text-slate-600 transition"
                          >
                            <FolderOpen className="h-3.5 w-3.5" style={{ color: TEAL }} />
                            {t("actions.open")}
                          </Link>
                          <button
                            onClick={() => startEdit(p)}
                            disabled={saving}
                            className="h-8 w-8 rounded-xl border border-slate-200 bg-white hover:border-slate-300 hover:bg-slate-50 flex items-center justify-center transition"
                            title="Modifier"
                          >
                            <Pencil className="h-3.5 w-3.5 text-slate-500" />
                          </button>
                          <button
                            onClick={() => onDelete(p.id)}
                            disabled={saving}
                            className="h-8 w-8 rounded-xl border border-red-100 bg-red-50 hover:bg-red-100 flex items-center justify-center transition"
                            title="Supprimer"
                          >
                            <Trash2 className="h-3.5 w-3.5 text-red-500" />
                          </button>
                        </div>
                      </td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* ── Modal ───────────────────────────────────────────────────────────── */}
      {open && (
        <div className="fixed inset-0 z-[60]">
          <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={() => !saving && setOpen(false)} />

          <div className="absolute left-1/2 top-1/2 w-[94vw] max-w-2xl -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-slate-200 bg-white shadow-2xl overflow-hidden">

            {/* Modal header */}
            <div className="px-6 py-4 border-b border-slate-100 flex items-center justify-between gap-3"
              style={{ background: `linear-gradient(135deg, ${NAVY} 0%, ${NAVY2} 100%)` }}>
              <div className="text-white">
                <div className="font-bold text-base">
                  {form.id ? t("modal.edit_title") : t("modal.create_title")}
                </div>
                <div className="text-xs text-white/60 mt-0.5">
                  {t("modal.subtitle")}
                </div>
              </div>
              <button
                onClick={() => !saving && setOpen(false)}
                disabled={saving}
                className="h-8 w-8 rounded-xl bg-white/10 hover:bg-white/20 flex items-center justify-center text-white transition"
              >
                <X className="h-4 w-4" />
              </button>
            </div>

            {/* Modal body */}
            <div className="p-6 space-y-4 max-h-[70vh] overflow-y-auto">
              {/* Nom + Code */}
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">
                    {t("modal.name_label")} <span className="text-red-400">*</span>
                  </label>
                  <input
                    className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm focus:border-teal-400 focus:ring-2 focus:ring-teal-400/20 outline-none transition"
                    value={form.name}
                    onChange={e => setForm(s => ({ ...s, name: e.target.value }))}
                    disabled={saving}
                  />
                </div>
                <div>
                  <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.code_label")}</label>
                  <input
                    className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm font-mono focus:border-teal-400 focus:ring-2 focus:ring-teal-400/20 outline-none transition"
                    value={form.code}
                    onChange={e => setForm(s => ({ ...s, code: e.target.value }))}
                    disabled={saving}
                    placeholder="PF-001"
                  />
                </div>
              </div>

              {/* Priorité + Devise + Responsable */}
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                <div>
                  <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.priority_label")}</label>
                  <select
                    className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm bg-white focus:border-teal-400 outline-none transition"
                    value={form.priority}
                    onChange={e => setForm(s => ({ ...s, priority: e.target.value as any }))}
                    disabled={saving}
                  >
                    <option value="low">{t("priority.low")}</option>
                    <option value="medium">{t("priority.medium")}</option>
                    <option value="high">{t("priority.high")}</option>
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.currency_label")}</label>
                  <SearchableSelect
                    value={(form.default_currency || "").toUpperCase()}
                    onChange={v => setForm(s => ({ ...s, default_currency: v }))}
                    options={currencyOptions}
                    placeholder={t("modal.currency_label")}
                    noResults={t("no_results")}
                    disabled={saving}
                    icon={<Coins className="h-3.5 w-3.5" />}
                  />
                </div>
                <div>
                  <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.owner_label")}</label>
                  <SearchableSelect
                    value={form.owner}
                    onChange={v => setForm(s => ({ ...s, owner: v }))}
                    options={[{ value: "", label: t("modal.none") }, ...ownerOptions]}
                    placeholder={t("modal.owner_label")}
                    noResults={t("no_results")}
                    disabled={saving}
                    icon={<UserRound className="h-3.5 w-3.5" />}
                  />
                </div>
              </div>

              {/* Catégorie */}
              <div>
                <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.category_label")}</label>
                <input
                  className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm focus:border-teal-400 focus:ring-2 focus:ring-teal-400/20 outline-none transition"
                  value={form.category}
                  onChange={e => setForm(s => ({ ...s, category: e.target.value }))}
                  disabled={saving}
                />
              </div>

              {/* Description */}
              <div>
                <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">{t("modal.description_label")}</label>
                <textarea
                  className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm resize-none focus:border-teal-400 focus:ring-2 focus:ring-teal-400/20 outline-none transition"
                  value={form.description}
                  onChange={e => setForm(s => ({ ...s, description: e.target.value }))}
                  disabled={saving}
                  rows={3}
                />
              </div>

              {/* Notes internes */}
              <div>
                <label className="block text-xs font-semibold text-slate-600 mb-1.5 uppercase tracking-wide">
                  {t("modal.notes_label")}
                  <span className="ml-1.5 font-normal text-slate-400 normal-case">({t("modal.notes_hint")})</span>
                </label>
                <textarea
                  className="w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm resize-none focus:border-teal-400 focus:ring-2 focus:ring-teal-400/20 outline-none transition"
                  value={form.internal_notes}
                  onChange={e => setForm(s => ({ ...s, internal_notes: e.target.value }))}
                  disabled={saving}
                  rows={2}
                />
              </div>

              {/* Actif toggle */}
              <label className="flex items-center gap-3 cursor-pointer p-3 rounded-xl border border-slate-200 bg-slate-50 hover:bg-slate-100 transition">
                <div className="relative">
                  <input type="checkbox" className="sr-only"
                    checked={form.is_active}
                    onChange={e => setForm(s => ({ ...s, is_active: e.target.checked }))}
                    disabled={saving}
                  />
                  <div className={cx(
                    "w-10 h-5 rounded-full transition-colors",
                    form.is_active ? "bg-teal-500" : "bg-slate-300"
                  )} style={form.is_active ? { background: TEAL } : {}} />
                  <div className={cx(
                    "absolute top-0.5 left-0.5 h-4 w-4 rounded-full bg-white shadow transition-transform",
                    form.is_active && "translate-x-5"
                  )} />
                </div>
                <div>
                  <div className="text-sm font-medium text-slate-700">{t("modal.active_label")}</div>
                  <div className="text-xs text-slate-400">{t("modal.active_hint")}</div>
                </div>
              </label>

              {error && (
                <div className="rounded-xl border border-red-100 bg-red-50 px-4 py-3 text-sm text-red-700">
                  {error}
                </div>
              )}
            </div>

            {/* Modal footer */}
            <div className="px-6 py-4 border-t border-slate-100 flex items-center justify-end gap-2 bg-slate-50/50">
              <button
                onClick={() => !saving && setOpen(false)}
                disabled={saving}
                className="rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50 transition inline-flex items-center gap-2"
              >
                <X className="h-4 w-4" /> {t("modal.cancel")}
              </button>
              <button
                onClick={onSave}
                disabled={saving}
                className="rounded-xl px-5 py-2 text-sm font-semibold text-white inline-flex items-center gap-2 transition hover:opacity-90 disabled:opacity-50"
                style={{ background: saving ? "#94a3b8" : NAVY }}
              >
                {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
                {saving ? t("modal.saving") : t("modal.save")}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}
