import { Badge } from "@/components/ui/badge";
import { Card, CardBody, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { DonutChart } from "@/components/ui/charts/donut-chart";
import { BarChart } from "@/components/ui/charts/bar-chart";
import {
  getApiMetricsSummary,
  topEndpoints24h,
  listAlertThresholds,
  recentSuspiciousCalls,
} from "@/lib/db/queries/monitoring";
import {
  apiCallsPerHour24h,
  apiStatusBuckets24h,
} from "@/lib/db/queries/charts";
import { logActivity } from "@/lib/db/audit";
import { getSession } from "@/lib/auth/session";

export const dynamic = "force-dynamic";

const numFmt = new Intl.NumberFormat("fr-FR");
const dateTimeFmt = new Intl.DateTimeFormat("fr-FR", {
  day: "2-digit",
  month: "short",
  hour: "2-digit",
  minute: "2-digit",
});

function statusTone(status: number | null): "success" | "warning" | "danger" | "neutral" {
  if (!status) return "neutral";
  if (status >= 500) return "danger";
  if (status >= 400) return "warning";
  if (status >= 200 && status < 300) return "success";
  return "neutral";
}

export default async function MonitoringPage() {
  const session = await getSession();
  let summary: Awaited<ReturnType<typeof getApiMetricsSummary>> | null = null;
  let endpoints: Awaited<ReturnType<typeof topEndpoints24h>> = [];
  let thresholds: Awaited<ReturnType<typeof listAlertThresholds>> = [];
  let suspicious: Awaited<ReturnType<typeof recentSuspiciousCalls>> = [];
  let hourly: Awaited<ReturnType<typeof apiCallsPerHour24h>> = [];
  let statusBuckets: Awaited<ReturnType<typeof apiStatusBuckets24h>> = [];
  let loadError: string | null = null;
  try {
    [summary, endpoints, thresholds, suspicious, hourly, statusBuckets] =
      await Promise.all([
        getApiMetricsSummary(),
        topEndpoints24h(),
        listAlertThresholds(),
        recentSuspiciousCalls(),
        apiCallsPerHour24h(),
        apiStatusBuckets24h(),
      ]);
    void logActivity({
      type: "superadmin.monitoring_view",
      title: "Vue monitoring API",
      user_id: session?.user.id,
    });
  } catch (err) {
    loadError = err instanceof Error ? err.message : "Erreur inconnue";
  }

  return (
    <div className="px-6 py-6 lg:px-10">
      <header className="mb-6">
        <h1 className="text-2xl font-semibold">Monitoring</h1>
        <p className="text-sm text-muted-foreground">
          Santé de l&apos;API, métriques sur 24 h, alertes de sécurité.
        </p>
      </header>

      {loadError && (
        <div className="rounded-md border border-red-200 bg-danger-subtle px-4 py-3 text-sm text-danger">
          Impossible de charger les métriques : {loadError}
        </div>
      )}

      {!loadError && summary && (
        <>
          <section className="mb-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            <KpiTile
              label="Requêtes 24 h"
              value={numFmt.format(summary.last_24h)}
              hint={`${numFmt.format(summary.total)} au total`}
            />
            <KpiTile
              label="Erreurs 5xx (24 h)"
              value={numFmt.format(summary.errors_5xx_24h)}
              tone={summary.errors_5xx_24h > 0 ? "danger" : "success"}
            />
            <KpiTile
              label="Suspect / rate-limit"
              value={`${summary.suspicious_24h} / ${summary.rate_limit_24h}`}
              tone={
                summary.suspicious_24h + summary.rate_limit_24h > 0
                  ? "warning"
                  : "success"
              }
              hint="suspicious / rate-limit dépassé"
            />
            <KpiTile
              label="Latence moy."
              value={
                summary.median_latency_ms
                  ? `${Math.round(summary.median_latency_ms)} ms`
                  : "—"
              }
              hint={
                summary.p95_latency_ms
                  ? `max ${Math.round(summary.p95_latency_ms)} ms`
                  : undefined
              }
            />
          </section>

          {/* M1 sparkline horaire + M2 donut status codes + M5 bar groupé */}
          <section className="mb-6 grid gap-4 lg:grid-cols-3">
            <Card className="lg:col-span-2">
              <CardHeader>
                <CardTitle>Trafic API — 24 h glissantes</CardTitle>
                <CardDescription>
                  Volume horaire ventilé : total / 4xx / 5xx.
                </CardDescription>
              </CardHeader>
              <CardBody>
                <BarChart
                  mode="grouped"
                  height={180}
                  data={hourly.map((h) => ({
                    label: h.hour_label,
                    values: [h.total, h.errors_4xx, h.errors_5xx],
                  }))}
                  series={[
                    { name: "Total", color: "var(--accent)" },
                    { name: "4xx", color: "var(--warning)" },
                    { name: "5xx", color: "var(--danger)" },
                  ]}
                />
              </CardBody>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Status codes — 24 h</CardTitle>
              </CardHeader>
              <CardBody>
                <DonutChart
                  segments={statusBuckets
                    .filter((s) => s.count > 0)
                    .map((s) => ({
                      label: s.bucket,
                      value: s.count,
                      color:
                        s.bucket === "2xx"
                          ? "var(--success)"
                          : s.bucket === "3xx"
                          ? "var(--accent)"
                          : s.bucket === "4xx"
                          ? "var(--warning)"
                          : s.bucket === "5xx"
                          ? "var(--danger)"
                          : "var(--muted-foreground)",
                    }))}
                  centerValue={numFmt.format(summary.last_24h)}
                  centerLabel="Calls"
                />
              </CardBody>
            </Card>
          </section>

          {/* M3 : Bar horizontal top endpoints */}
          {endpoints.length > 0 && (
            <section className="mb-6">
              <Card>
                <CardHeader>
                  <CardTitle>Top endpoints 24 h</CardTitle>
                  <CardDescription>
                    Trié par volume de hits. Latence et erreurs détaillées en table ci-dessous.
                  </CardDescription>
                </CardHeader>
                <CardBody>
                  <BarChart
                    orientation="horizontal"
                    data={endpoints.map((e) => ({
                      label: `${e.method} ${e.endpoint}`,
                      values: [e.hits_24h],
                    }))}
                    series={[
                      {
                        name: "Hits",
                        color: "var(--accent)",
                      },
                    ]}
                    showValues
                    legend={false}
                    formatValue={(v) => numFmt.format(v)}
                  />
                </CardBody>
              </Card>
            </section>
          )}

          {endpoints.length > 0 && (
            <section className="mb-6">
              <h2 className="mb-2 text-sm font-medium uppercase tracking-wider text-muted-foreground">
                Top endpoints — détail
              </h2>
              <div className="overflow-hidden rounded-lg border border-border bg-surface">
                <table className="w-full text-sm">
                  <thead className="bg-surface-2 text-left text-[11px] font-medium uppercase tracking-wider text-muted-foreground">
                    <tr>
                      <th className="px-4 py-2.5">Endpoint</th>
                      <th className="px-4 py-2.5">Méthode</th>
                      <th className="px-4 py-2.5 text-right">Hits</th>
                      <th className="px-4 py-2.5 text-right">Latence moy.</th>
                      <th className="px-4 py-2.5 text-right">Erreurs</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-border">
                    {endpoints.map((e) => (
                      <tr
                        key={`${e.method}-${e.endpoint}`}
                        className="hover:bg-surface-2/60"
                      >
                        <td className="px-4 py-2 font-mono text-xs">
                          {e.endpoint}
                        </td>
                        <td className="px-4 py-2">
                          <Badge tone="neutral">{e.method}</Badge>
                        </td>
                        <td className="px-4 py-2 text-right tabular-nums">
                          {numFmt.format(e.hits_24h)}
                        </td>
                        <td className="px-4 py-2 text-right text-xs tabular-nums">
                          {e.avg_latency_ms
                            ? `${Math.round(e.avg_latency_ms)} ms`
                            : "—"}
                        </td>
                        <td className="px-4 py-2 text-right tabular-nums">
                          {e.errors_24h > 0 ? (
                            <span className="text-danger font-medium">
                              {numFmt.format(e.errors_24h)}
                            </span>
                          ) : (
                            <span className="text-muted-foreground">0</span>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </section>
          )}

          <section className="mb-6 grid gap-4 lg:grid-cols-2">
            <div>
              <h2 className="mb-2 text-sm font-medium uppercase tracking-wider text-muted-foreground">
                Seuils d&apos;alerte ({thresholds.length})
              </h2>
              <div className="overflow-hidden rounded-lg border border-border bg-surface">
                {thresholds.length === 0 ? (
                  <p className="px-4 py-6 text-center text-sm text-muted-foreground">
                    Aucun seuil configuré.
                  </p>
                ) : (
                  <ul className="divide-y divide-border">
                    {thresholds.map((t) => (
                      <li
                        key={t.id}
                        className="flex items-center gap-3 px-4 py-2 text-sm"
                      >
                        <Badge tone={t.is_active ? "success" : "neutral"}>
                          {t.is_active ? "actif" : "off"}
                        </Badge>
                        <span className="font-mono text-xs">
                          {t.metric_name}
                        </span>
                        <span className="ml-auto text-xs text-muted-foreground tabular-nums">
                          ≥ {t.threshold_value} sur {t.time_window_minutes} min
                          → {t.alert_type}
                        </span>
                      </li>
                    ))}
                  </ul>
                )}
              </div>
            </div>

            <div>
              <h2 className="mb-2 text-sm font-medium uppercase tracking-wider text-muted-foreground">
                Activité suspecte récente
              </h2>
              <div className="overflow-hidden rounded-lg border border-border bg-surface">
                {suspicious.length === 0 ? (
                  <p className="px-4 py-6 text-center text-sm text-muted-foreground">
                    Aucune anomalie détectée.
                  </p>
                ) : (
                  <ul className="divide-y divide-border max-h-80 overflow-y-auto">
                    {suspicious.map((s) => (
                      <li key={s.id} className="px-4 py-2 text-xs">
                        <div className="flex flex-wrap items-center gap-2">
                          <Badge tone={statusTone(s.response_status)}>
                            {s.response_status ?? "—"}
                          </Badge>
                          <span className="font-mono text-foreground">
                            {s.method} {s.endpoint}
                          </span>
                          {s.is_suspicious === 1 && (
                            <Badge tone="warning">suspect</Badge>
                          )}
                          {s.rate_limit_exceeded === 1 && (
                            <Badge tone="danger">rate-limit</Badge>
                          )}
                          <span className="ml-auto text-muted-foreground tabular-nums">
                            {dateTimeFmt.format(new Date(s.timestamp))}
                          </span>
                        </div>
                        <div className="mt-0.5 text-muted-foreground">
                          {s.source_ip ?? "ip ?"}
                          {s.user_name ? ` · ${s.user_name}` : ""}
                          {s.response_time_ms
                            ? ` · ${s.response_time_ms} ms`
                            : ""}
                        </div>
                      </li>
                    ))}
                  </ul>
                )}
              </div>
            </div>
          </section>
        </>
      )}
    </div>
  );
}

function KpiTile({
  label,
  value,
  hint,
  tone = "neutral",
}: {
  label: string;
  value: string;
  hint?: string;
  tone?: "neutral" | "success" | "warning" | "danger";
}) {
  const toneCls = {
    neutral: "text-foreground",
    success: "text-success",
    warning: "text-warning",
    danger: "text-danger",
  }[tone];
  return (
    <div className="rounded-lg border border-border bg-surface p-4">
      <p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
        {label}
      </p>
      <p className={`mt-1 text-2xl font-semibold tabular-nums ${toneCls}`}>
        {value}
      </p>
      {hint && (
        <p className="mt-1 text-[11px] text-muted-foreground">{hint}</p>
      )}
    </div>
  );
}
