import { asc, eq } from "drizzle-orm";
import {
  Globe,
  MousePointerClick,
  Eye,
  Target,
  TrendingUp,
  Users,
  Clock,
  ArrowDownRight,
  Info,
} from "@/components/ui/icons";
import { Topbar } from "@/components/shell/topbar";
import { Panel, PanelHeader } from "@/components/ui/panel";
import { Badge } from "@/components/ui/badge";
import { StatCard } from "@/components/ui/stat-card";
import { EmptyState } from "@/components/ui/empty-state";
import { SiteSwitcher } from "@/components/portail/site-switcher";
import { PortalCharts } from "@/components/portail/portal-charts";
import { SectionStamp } from "@/components/marketing/section-stamp";
import { requireUser } from "@/lib/auth/server";
import { db } from "@/lib/db";
import { clientSite } from "@/lib/db/schema";
import {
  fetchSearchConsoleMetrics,
  fetchAnalyticsMetrics,
  mergeDailySeries,
  DEFAULT_WINDOW_DAYS,
} from "@/lib/google-fetchers";
import { formatNumber } from "@/lib/format";

// Cache 30 min : evite de spammer les APIs Google a chaque render.
export const revalidate = 1800;

type SearchParams = Promise<{ site?: string }>;

export default async function PortalDashboard({
  searchParams,
}: {
  searchParams: SearchParams;
}) {
  const session = await requireUser();
  const params = await searchParams;
  const firstName = (session.user.name || session.user.email).split(/[ @]/)[0];

  const clientAccountId = session.user.clientAccountId;

  // === Pas de compte client rattache (admin Novelia connecte au portail, ou compte non provisionne) ===
  if (!clientAccountId) {
    return (
      <>
        <Topbar
          eyebrow={<SectionStamp number="C" label="Espace client" />}
          title={`Bonjour, ${firstName}`}
          subtitle="Tableau de bord de votre site"
        />
        <div className="pt-8">
          <Panel>
            <EmptyState
              icon={Globe}
              title="Aucun compte client rattache"
              description="Votre compte n'est pas encore associe a un compte client. Contactez l'agence pour finaliser votre acces."
            />
          </Panel>
        </div>
      </>
    );
  }

  // === Sites rattaches au compte client ===
  const sites = await db
    .select()
    .from(clientSite)
    .where(eq(clientSite.clientAccountId, clientAccountId))
    .orderBy(asc(clientSite.createdAt));

  if (sites.length === 0) {
    return (
      <>
        <Topbar
          eyebrow={<SectionStamp number="C" label="Espace client" />}
          title={`Bonjour, ${firstName}`}
          subtitle="Tableau de bord de votre site"
        />
        <div className="pt-8">
          <Panel>
            <EmptyState
              icon={Globe}
              title="Aucun site connecte"
              description="Des que votre premier site est en ligne, vous retrouverez ici les chiffres de Search Console et Google Analytics."
            />
          </Panel>
        </div>
      </>
    );
  }

  // Selection du site : param ?site ou premier par defaut.
  const selectedSite = sites.find((s) => s.id === params.site) ?? sites[0];

  const switcherSites = sites.map((s) => ({
    id: s.id,
    domain: s.domain,
    label: s.label,
  }));

  // === Fetch parallele GSC + GA4 (renvoie null si non configure ou erreur) ===
  const [gsc, ga4] = await Promise.all([
    selectedSite.searchConsoleSiteUrl
      ? fetchSearchConsoleMetrics(selectedSite.searchConsoleSiteUrl)
      : Promise.resolve(null),
    selectedSite.ga4PropertyId
      ? fetchAnalyticsMetrics(selectedSite.ga4PropertyId)
      : Promise.resolve(null),
  ]);

  // Banniere d'info quand le site n'a pas encore ses identifiants Google.
  const awaitingConnection =
    !selectedSite.searchConsoleSiteUrl && !selectedSite.ga4PropertyId;

  // Serie quotidienne : si pas de data, on genere 28 jours a 0 pour que le
  // graphique se rende quand meme avec la grille et les axes.
  const dailySeries = (() => {
    const merged = mergeDailySeries(gsc?.dailySeries ?? null, ga4?.dailySeries ?? null);
    if (merged.length > 0) return merged;
    return generateEmptyDailySeries(DEFAULT_WINDOW_DAYS);
  })();

  return (
    <>
      <Topbar
        eyebrow={<SectionStamp number="C" label="Espace client" />}
        title={`Bonjour, ${firstName}`}
        subtitle={`Tableau de bord de ${selectedSite.label ?? selectedSite.domain}`}
        trailing={
          <div className="flex items-center gap-2">
            <Badge tone="muted">{DEFAULT_WINDOW_DAYS} derniers jours</Badge>
            <SiteSwitcher sites={switcherSites} selectedId={selectedSite.id} />
          </div>
        }
      />

      <div className="pt-6 space-y-6">
        {awaitingConnection ? (
          <div
            role="status"
            className="flex items-start gap-3 rounded-lg border border-accent/40 bg-accent-soft px-4 py-3 text-sm text-text"
          >
            <Info aria-hidden className="size-4 text-accent shrink-0 mt-0.5" />
            <span>
              Search Console et Google Analytics ne sont pas encore branches sur ce
              site. L&apos;equipe Novelia est en train de finaliser la connexion :
              les chiffres apparaitront ici sous quelques jours.
            </span>
          </div>
        ) : null}

        {/* KPI grid : 8 cards uniformes, lecture rapide cote client.
            On a essaye un KpiHero featured + grille secondaire, le format 4
            carre par row a ete repris a la demande. */}
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
          <StatCard
            label="Clics organiques"
            value={formatNumber(gsc?.clicks ?? 0)}
            delta={gsc ? Number(gsc.deltas.clicks.toFixed(1)) : undefined}
            deltaSuffix="vs periode precedente"
            icon={MousePointerClick}
          />
          <StatCard
            label="Impressions"
            value={formatNumber(gsc?.impressions ?? 0)}
            delta={gsc ? Number(gsc.deltas.impressions.toFixed(1)) : undefined}
            deltaSuffix="vs periode precedente"
            icon={Eye}
          />
          <StatCard
            label="CTR moyen"
            value={`${((gsc?.ctr ?? 0) * 100).toFixed(2)}%`}
            delta={gsc ? Number(gsc.deltas.ctr.toFixed(2)) : undefined}
            deltaSuffix="points"
            icon={Target}
          />
          <StatCard
            label="Position moyenne"
            value={gsc ? gsc.position.toFixed(1) : "—"}
            delta={gsc ? Number((-gsc.deltas.position).toFixed(2)) : undefined}
            deltaSuffix="places gagnees"
            icon={TrendingUp}
          />
          <StatCard
            label="Sessions"
            value={formatNumber(ga4?.sessions ?? 0)}
            delta={ga4 ? Number(ga4.deltas.sessions.toFixed(1)) : undefined}
            deltaSuffix="vs periode precedente"
            icon={Users}
          />
          <StatCard
            label="Visiteurs uniques"
            value={formatNumber(ga4?.users ?? 0)}
            delta={ga4 ? Number(ga4.deltas.users.toFixed(1)) : undefined}
            deltaSuffix="vs periode precedente"
            icon={Users}
          />
          <StatCard
            label="Duree moyenne"
            value={formatDuration(ga4?.avgDurationSec ?? 0)}
            delta={ga4 ? Number(ga4.deltas.avgDurationSec.toFixed(1)) : undefined}
            deltaSuffix="vs periode precedente"
            icon={Clock}
          />
          <StatCard
            label="Taux de rebond"
            value={`${((ga4?.bounceRate ?? 0) * 100).toFixed(1)}%`}
            delta={ga4 ? Number(ga4.deltas.bounceRate.toFixed(2)) : undefined}
            deltaSuffix="points"
            deltaInverted
            icon={ArrowDownRight}
          />
        </div>

        {/* Graph + Top queries */}
        <div className="grid grid-cols-1 xl:grid-cols-3 gap-6">
          <div className="xl:col-span-2">
            <Panel>
              <PanelHeader
                title="Trafic sur 28 jours"
                subtitle={
                  gsc && ga4
                    ? "Clics, impressions et sessions analytiques"
                    : gsc
                      ? "Clics et impressions (Search Console)"
                      : "Sessions (Google Analytics)"
                }
              />
              <div className="px-2 py-4">
                <PortalCharts
                  data={dailySeries}
                  showClicks={Boolean(gsc) || !ga4}
                  showImpressions={Boolean(gsc)}
                  showSessions={Boolean(ga4)}
                />
              </div>
            </Panel>
          </div>

          <Panel>
            <PanelHeader title="Top requetes" subtitle="Les recherches qui amenent du trafic" />
            {gsc?.topQueries?.length ? (
              <ul className="divide-y divide-border">
                {gsc.topQueries.slice(0, 8).map((q) => (
                  <li key={q.query} className="px-5 py-2.5 flex items-center justify-between gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="text-sm text-text truncate">{q.query}</div>
                      <div className="text-xxs text-text-faint">
                        {formatNumber(q.impressions)} impressions, position {q.position.toFixed(1)}
                      </div>
                    </div>
                    <div className="text-sm tabular-nums font-semibold text-text shrink-0">
                      {formatNumber(q.clicks)}
                    </div>
                  </li>
                ))}
              </ul>
            ) : (
              <EmptyState
                title="Pas encore de requetes mesurees"
                description="Search Console accumule les donnees sur les premiers jours."
                compact
              />
            )}
          </Panel>
        </div>

        {/* Top pages + Sources */}
        <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
          <Panel>
            <PanelHeader title="Pages les plus visitees" subtitle="Top 8 sur 28 jours" />
            {ga4?.topPages?.length ? (
              <ul className="divide-y divide-border">
                {ga4.topPages.slice(0, 8).map((p) => (
                  <li
                    key={p.path + p.title}
                    className="px-5 py-2.5 flex items-center justify-between gap-3"
                  >
                    <div className="min-w-0 flex-1">
                      <div className="text-sm text-text truncate">{p.title || p.path}</div>
                      <div className="text-xxs font-mono text-text-faint truncate">{p.path}</div>
                    </div>
                    <div className="text-sm tabular-nums font-semibold text-text shrink-0">
                      {formatNumber(p.sessions)}
                    </div>
                  </li>
                ))}
              </ul>
            ) : (
              <EmptyState
                title="Pas de pages mesurees"
                description="Google Analytics n'a pas encore enregistre de sessions."
                compact
              />
            )}
          </Panel>

          <Panel>
            <PanelHeader title="Sources de trafic" subtitle="D'ou viennent vos visiteurs" />
            {ga4?.trafficSources?.length ? (
              <ul className="divide-y divide-border">
                {ga4.trafficSources.slice(0, 8).map((s) => (
                  <li key={s.source} className="px-5 py-3 flex items-center gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="text-sm text-text truncate">{s.source}</div>
                      <div className="mt-1 h-1 rounded-full bg-stone-900/[0.06] overflow-hidden">
                        <div
                          className="h-full bg-accent"
                          style={{ width: `${Math.min(100, s.share * 100).toFixed(1)}%` }}
                        />
                      </div>
                    </div>
                    <div className="text-right shrink-0">
                      <div className="text-sm tabular-nums font-semibold text-text">
                        {formatNumber(s.sessions)}
                      </div>
                      <div className="text-xxs text-text-faint">
                        {(s.share * 100).toFixed(1)}%
                      </div>
                    </div>
                  </li>
                ))}
              </ul>
            ) : (
              <EmptyState
                title="Sources non disponibles"
                description="Aucune donnee analytique pour le moment."
                compact
              />
            )}
          </Panel>
        </div>

        <p className="text-xxs text-text-faint text-center">
          Donnees rafraichies toutes les 30 minutes. Periode : {DEFAULT_WINDOW_DAYS} derniers jours.
        </p>
      </div>
    </>
  );
}

function formatDuration(seconds: number): string {
  if (!seconds || !isFinite(seconds)) return "0s";
  const m = Math.floor(seconds / 60);
  const s = Math.round(seconds - m * 60);
  if (m === 0) return `${s}s`;
  return `${m}m ${s.toString().padStart(2, "0")}s`;
}

// Genere une serie de N jours a 0 pour rendre le graphique meme sans donnees.
// L'echelle des dates est correcte ce qui donne la grille temporelle attendue.
function generateEmptyDailySeries(days: number) {
  const out: Array<{ date: string; clicks: number; impressions: number; sessions: number }> = [];
  const end = new Date();
  end.setUTCHours(0, 0, 0, 0);
  end.setUTCDate(end.getUTCDate() - 1);
  for (let i = days - 1; i >= 0; i--) {
    const d = new Date(end);
    d.setUTCDate(d.getUTCDate() - i);
    out.push({ date: d.toISOString().slice(0, 10), clicks: 0, impressions: 0, sessions: 0 });
  }
  return out;
}
