import { db, schema } from "@/lib/db";
import { desc, sql, count, sum, and, gte, eq } from "drizzle-orm";
import Icon from "@/components/Icon";
import Link from "next/link";

export const metadata = { title: "Dashboard" };

function formatEuros(cents: number): string {
  return new Intl.NumberFormat("fr-FR", {
    style: "currency",
    currency: "EUR",
    maximumFractionDigits: 0,
  }).format(cents / 100);
}

async function getMetrics() {
  const now = new Date();
  const startOfWeek = new Date(now);
  const day = startOfWeek.getDay() || 7; // Lundi = 1
  startOfWeek.setDate(startOfWeek.getDate() - day + 1);
  startOfWeek.setHours(0, 0, 0, 0);

  const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
  const startOfYear = new Date(now.getFullYear(), 0, 1);

  const paidWhere = eq(schema.invoice.status, "payee");

  // CA semaine / mois / année (somme amountCents des factures payées sur la
  // période).
  const [weekSum, monthSum, yearSum] = await Promise.all([
    db
      .select({ total: sum(schema.invoice.amountCents) })
      .from(schema.invoice)
      .where(and(paidWhere, gte(schema.invoice.paidAt, startOfWeek))),
    db
      .select({ total: sum(schema.invoice.amountCents) })
      .from(schema.invoice)
      .where(and(paidWhere, gte(schema.invoice.paidAt, startOfMonth))),
    db
      .select({ total: sum(schema.invoice.amountCents) })
      .from(schema.invoice)
      .where(and(paidWhere, gte(schema.invoice.paidAt, startOfYear))),
  ]);

  // Détail jour par jour pour la semaine (chart).
  const weekByDay = await db
    .select({
      day: sql<string>`date_trunc('day', ${schema.invoice.paidAt})::date`,
      total: sum(schema.invoice.amountCents).mapWith(Number),
    })
    .from(schema.invoice)
    .where(and(paidWhere, gte(schema.invoice.paidAt, startOfWeek)))
    .groupBy(sql`date_trunc('day', ${schema.invoice.paidAt})`);

  // Dernières factures + dossiers
  const [recentInvoices, recentDossiers] = await Promise.all([
    db
      .select({
        id: schema.invoice.id,
        number: schema.invoice.number,
        amountCents: schema.invoice.amountCents,
        status: schema.invoice.status,
        createdAt: schema.invoice.createdAt,
        clientName: schema.user.name,
      })
      .from(schema.invoice)
      .leftJoin(schema.user, eq(schema.invoice.clientId, schema.user.id))
      .orderBy(desc(schema.invoice.createdAt))
      .limit(5),
    db
      .select({
        id: schema.dossier.id,
        reference: schema.dossier.reference,
        title: schema.dossier.title,
        status: schema.dossier.status,
        createdAt: schema.dossier.createdAt,
        clientName: schema.user.name,
      })
      .from(schema.dossier)
      .leftJoin(schema.user, eq(schema.dossier.clientId, schema.user.id))
      .orderBy(desc(schema.dossier.createdAt))
      .limit(5),
  ]);

  const [{ count: clientsCount }] = await db
    .select({ count: count() })
    .from(schema.user)
    .where(eq(schema.user.role, "client"));

  return {
    weekTotal: Number(weekSum[0].total ?? 0),
    monthTotal: Number(monthSum[0].total ?? 0),
    yearTotal: Number(yearSum[0].total ?? 0),
    weekByDay,
    recentInvoices,
    recentDossiers,
    clientsCount,
    weekStart: startOfWeek,
  };
}

export default async function AdminDashboardPage() {
  const m = await getMetrics();

  return (
    <div className="space-y-12 max-w-7xl">
      <header>
        <span className="eyebrow">Tableau de bord</span>
        <h1 className="display-lg !text-4xl text-primary mt-2">
          Vue d'ensemble
        </h1>
      </header>

      {/* KPIs */}
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        <Kpi label="CA cette semaine" value={formatEuros(m.weekTotal)} />
        <Kpi label="CA ce mois" value={formatEuros(m.monthTotal)} />
        <Kpi label="CA cette année" value={formatEuros(m.yearTotal)} />
      </div>

      {/* Visu CA par jour de la semaine — placeholder simple bar chart maison */}
      <section className="bg-white border border-outline-variant p-8 lg:p-10">
        <header className="flex items-end justify-between mb-8">
          <div>
            <span className="eyebrow !text-on-surface-variant">
              CA quotidien · semaine en cours
            </span>
            <h2 className="font-serif text-2xl text-primary mt-1">
              Lun → Dim
            </h2>
          </div>
          <p className="text-xs text-on-surface-variant font-serif uppercase tracking-widest">
            {m.weekStart.toLocaleDateString("fr-FR", {
              day: "numeric",
              month: "long",
            })}{" "}
            →
          </p>
        </header>
        <WeekChart data={m.weekByDay} weekStart={m.weekStart} />
      </section>

      {/* Dernières factures + Derniers dossiers */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <Panel
          title="Dernières factures"
          link={{ href: "/socialexadmin/factures", label: "Voir tout" }}
        >
          {m.recentInvoices.length === 0 ? (
            <Empty label="Aucune facture pour l'instant." />
          ) : (
            <ul className="divide-y divide-outline-variant/40">
              {m.recentInvoices.map((inv) => (
                <li
                  key={inv.id}
                  className="py-4 flex items-center justify-between gap-4"
                >
                  <div className="min-w-0">
                    <p className="font-serif text-sm text-primary truncate">
                      {inv.number}
                    </p>
                    <p className="text-xs text-on-surface-variant truncate">
                      {inv.clientName ?? "Client supprimé"}
                    </p>
                  </div>
                  <div className="text-right shrink-0">
                    <p className="text-sm text-primary">
                      {formatEuros(inv.amountCents)}
                    </p>
                    <StatusBadge status={inv.status} />
                  </div>
                </li>
              ))}
            </ul>
          )}
        </Panel>

        <Panel
          title="Derniers dossiers"
          link={{
            href: "/socialexadmin/dossiers/en-cours",
            label: "Voir tout",
          }}
        >
          {m.recentDossiers.length === 0 ? (
            <Empty label="Aucun dossier pour l'instant." />
          ) : (
            <ul className="divide-y divide-outline-variant/40">
              {m.recentDossiers.map((d) => (
                <li
                  key={d.id}
                  className="py-4 flex items-center justify-between gap-4"
                >
                  <div className="min-w-0">
                    <p className="font-serif text-sm text-primary truncate">
                      {d.title}
                    </p>
                    <p className="text-xs text-on-surface-variant truncate">
                      {d.reference} · {d.clientName ?? "Client supprimé"}
                    </p>
                  </div>
                  <StatusBadge status={d.status} />
                </li>
              ))}
            </ul>
          )}
        </Panel>
      </div>
    </div>
  );
}

/* ─── Sub-components ────────────────────────────────────────────────── */

function Kpi({ label, value }: { label: string; value: string }) {
  return (
    <div className="bg-white border border-outline-variant p-8">
      <p className="eyebrow !text-on-surface-variant mb-3">{label}</p>
      <p className="font-serif font-medium text-4xl text-secondary tracking-[-0.02em]">
        {value}
      </p>
    </div>
  );
}

function Panel({
  title,
  link,
  children,
}: {
  title: string;
  link?: { href: string; label: string };
  children: React.ReactNode;
}) {
  return (
    <section className="bg-white border border-outline-variant p-8">
      <header className="flex items-baseline justify-between mb-6">
        <h3 className="font-serif text-xl text-primary">{title}</h3>
        {link && (
          <Link
            href={link.href}
            className="text-xs uppercase tracking-widest font-serif text-on-surface-variant hover:text-primary transition-colors"
          >
            {link.label} →
          </Link>
        )}
      </header>
      {children}
    </section>
  );
}

function Empty({ label }: { label: string }) {
  return (
    <p className="text-sm text-on-surface-variant py-8 text-center italic">
      {label}
    </p>
  );
}

function StatusBadge({ status }: { status: string }) {
  const map: Record<string, { label: string; cls: string }> = {
    formulaire: { label: "Formulaire", cls: "bg-surface-container text-on-surface-variant" },
    en_attente_paiement: { label: "Attente paiement", cls: "bg-secondary-container text-on-secondary-container" },
    en_cours: { label: "En cours", cls: "bg-primary text-on-primary" },
    termine: { label: "Terminé", cls: "bg-secondary-container text-on-secondary-container" },
    annule: { label: "Annulé", cls: "bg-error-container text-on-error-container" },
    brouillon: { label: "Brouillon", cls: "bg-surface-container text-on-surface-variant" },
    envoyee: { label: "Envoyée", cls: "bg-secondary-container text-on-secondary-container" },
    payee: { label: "Payée", cls: "bg-primary text-on-primary" },
    annulee: { label: "Annulée", cls: "bg-error-container text-on-error-container" },
  };
  const { label, cls } = map[status] ?? { label: status, cls: "" };
  return (
    <span
      className={`inline-block px-2.5 py-1 text-[10px] uppercase tracking-widest font-serif ${cls}`}
    >
      {label}
    </span>
  );
}

function WeekChart({
  data,
  weekStart,
}: {
  data: { day: string; total: number }[];
  weekStart: Date;
}) {
  const days = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
  // Map day index → total (cents)
  const byIndex = new Array(7).fill(0);
  data.forEach((row) => {
    const d = new Date(row.day);
    const diffMs = d.getTime() - weekStart.getTime();
    const idx = Math.floor(diffMs / (1000 * 60 * 60 * 24));
    if (idx >= 0 && idx < 7) byIndex[idx] = row.total;
  });
  const max = Math.max(...byIndex, 1);

  return (
    <div className="grid grid-cols-7 gap-3 h-48 items-end">
      {byIndex.map((cents, i) => {
        const heightPct = (cents / max) * 100;
        return (
          <div key={i} className="flex flex-col items-center gap-2">
            <div className="flex-1 flex items-end w-full">
              <div
                className="w-full bg-primary transition-all duration-700"
                style={{ height: `${heightPct}%`, minHeight: cents > 0 ? 2 : 0 }}
                title={formatEuros(cents)}
              />
            </div>
            <p className="text-[10px] uppercase tracking-widest text-on-surface-variant font-serif">
              {days[i]}
            </p>
          </div>
        );
      })}
    </div>
  );
}
