"use client";

import type { ReactElement } from "react";
import { useTranslation } from "react-i18next";

import { cn } from "@/lib/utils";
import type { AdminDashboardAnalyticsPlayRow } from "@/types/api/admin-dashboard-analytics";
import type { AdminReportDailyProfitRow } from "@/types/api/admin-reports";
import type { DashboardAnalyticsMetric } from "@/types/api/admin-dashboard-analytics";

type MoneyFormatter = (minor: number, currency: string | null) => string;

function metricValue(row: AdminReportDailyProfitRow, metric: DashboardAnalyticsMetric): number {
  switch (metric) {
    case "bet":
      return row.total_bet_minor;
    case "payout":
      return row.total_payout_minor;
    case "profit":
      return row.approx_house_gross_minor;
    default:
      return row.total_bet_minor;
  }
}

function playMetricValue(row: AdminDashboardAnalyticsPlayRow, metric: DashboardAnalyticsMetric): number {
  switch (metric) {
    case "bet":
      return row.total_bet_minor;
    case "payout":
      return row.total_payout_minor;
    case "profit":
      return row.approx_house_gross_minor;
    default:
      return row.total_bet_minor;
  }
}

export function DailyTrendChart({
  series,
  metric,
  formatMoney,
  currency,
}: {
  series: AdminReportDailyProfitRow[];
  metric: DashboardAnalyticsMetric;
  formatMoney: MoneyFormatter;
  currency: string | null;
}): ReactElement {
  const { t } = useTranslation("dashboard");

  if (series.length === 0) {
    return <p className="py-10 text-center text-sm text-muted-foreground">{t("states.noData", { ns: "common" })}</p>;
  }

  const maxBet = Math.max(...series.map((d) => d.total_bet_minor), 1);
  const maxPayout = Math.max(...series.map((d) => d.total_payout_minor), 1);
  const maxProfit = Math.max(...series.map((d) => Math.abs(d.approx_house_gross_minor)), 1);
  const labelEvery = series.length > 14 ? Math.ceil(series.length / 7) : 1;

  const plotHeight = series.length <= 7 ? 200 : series.length <= 14 ? 220 : 240;

  return (
    <div className="flex flex-col gap-3">
      {metric === "overview" ? (
        <div className="flex shrink-0 flex-wrap gap-3 text-xs text-muted-foreground">
          <span className="inline-flex items-center gap-1.5">
            <span className="size-2.5 rounded-sm bg-primary" />
            {t("chartLegend.bet")}
          </span>
          <span className="inline-flex items-center gap-1.5">
            <span className="size-2.5 rounded-sm bg-rose-500" />
            {t("chartLegend.payout")}
          </span>
          <span className="inline-flex items-center gap-1.5">
            <span className="size-2.5 rounded-sm bg-emerald-500" />
            {t("chartLegend.profit")}
          </span>
        </div>
      ) : null}

      <div
        className="flex items-end gap-1 overflow-x-auto rounded-md border border-border/60 bg-muted/20 px-2 pb-2 pt-3 sm:gap-1.5"
        style={{ height: plotHeight }}
      >
        {series.map((day, idx) => {
          const betH = (day.total_bet_minor / maxBet) * 100;
          const payoutH = (day.total_payout_minor / maxPayout) * 100;
          const profitRaw = day.approx_house_gross_minor;
          const profitH = (Math.abs(profitRaw) / maxProfit) * 100;
          const showLabel = idx % labelEvery === 0 || idx === series.length - 1;
          const shortDate = day.business_date.slice(5);

          return (
            <div
              key={day.business_date}
              className="flex min-w-[28px] flex-1 flex-col items-stretch justify-end gap-1 self-stretch"
              title={`${day.business_date}\n${t("todayBetTotal")}: ${formatMoney(day.total_bet_minor, currency)}\n${t("todayPayout")}: ${formatMoney(day.total_payout_minor, currency)}\n${t("todayProfit")}: ${formatMoney(day.approx_house_gross_minor, currency)}`}
            >
              <div className="flex w-full flex-1 items-end justify-center gap-0.5">
                {metric === "overview" ? (
                  <>
                    <div
                      className="w-[30%] min-w-[4px] rounded-t-sm bg-primary/90 transition-all"
                      style={{ height: `${Math.max(betH, day.total_bet_minor > 0 ? 4 : 0)}%` }}
                    />
                    <div
                      className="w-[30%] min-w-[4px] rounded-t-sm bg-rose-500/90 transition-all"
                      style={{ height: `${Math.max(payoutH, day.total_payout_minor > 0 ? 4 : 0)}%` }}
                    />
                    <div
                      className={cn(
                        "w-[30%] min-w-[4px] rounded-t-sm transition-all",
                        profitRaw >= 0 ? "bg-emerald-500/90" : "bg-amber-500/90",
                      )}
                      style={{ height: `${Math.max(profitH, profitRaw !== 0 ? 4 : 0)}%` }}
                    />
                  </>
                ) : (
                  <div
                    className={cn(
                      "w-[70%] min-w-[6px] max-w-[20px] rounded-t-md transition-all",
                      metric === "payout" && "bg-rose-500/90",
                      metric === "profit" && (profitRaw >= 0 ? "bg-emerald-500/90" : "bg-amber-500/90"),
                      metric === "bet" && "bg-primary/90",
                    )}
                    style={{
                      height: `${Math.max(
                        (metricValue(day, metric) / (metric === "bet" ? maxBet : metric === "payout" ? maxPayout : maxProfit)) * 100,
                        metricValue(day, metric) !== 0 ? 6 : 0,
                      )}%`,
                    }}
                  />
                )}
              </div>
              <span
                className={cn(
                  "shrink-0 text-center text-[10px] tabular-nums text-muted-foreground",
                  !showLabel && "invisible",
                )}
              >
                {shortDate}
              </span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export function PlayBreakdownChart({
  rows,
  metric,
  formatMoney,
  currency,
  playLabel,
}: {
  rows: AdminDashboardAnalyticsPlayRow[];
  metric: DashboardAnalyticsMetric;
  formatMoney: MoneyFormatter;
  currency: string | null;
  playLabel: (code: string, dimension: number) => string;
}): ReactElement {
  const { t } = useTranslation("dashboard");

  if (rows.length === 0) {
    return <p className="py-10 text-center text-sm text-muted-foreground">{t("analytics.noPlayData")}</p>;
  }

  const max = Math.max(...rows.map((r) => Math.abs(playMetricValue(r, metric === "overview" ? "bet" : metric))), 1);
  const activeMetric = metric === "overview" ? "bet" : metric;

  return (
    <ul className="space-y-2.5">
      {rows.map((row) => {
        const value = playMetricValue(row, activeMetric);
        const pct = (Math.abs(value) / max) * 100;
        const label = playLabel(row.play_code, row.dimension);

        return (
          <li key={`${row.play_code}-${row.dimension}`}>
            <div className="mb-1 flex items-center justify-between gap-2 text-sm">
              <span className="truncate font-medium text-foreground">{label}</span>
              <span className="shrink-0 tabular-nums text-muted-foreground">{formatMoney(value, currency)}</span>
            </div>
            <div className="h-2 overflow-hidden rounded-full bg-muted">
              <div
                className={cn(
                  "h-full rounded-full transition-all",
                  activeMetric === "payout" && "bg-rose-500",
                  activeMetric === "profit" && (value >= 0 ? "bg-emerald-500" : "bg-amber-500"),
                  activeMetric === "bet" && "bg-primary",
                )}
                style={{ width: `${pct}%` }}
              />
            </div>
            {metric === "overview" ? (
              <p className="mt-0.5 line-clamp-1 text-[11px] text-muted-foreground">
                {t("playBreakdownHint", {
                  payout: formatMoney(row.total_payout_minor, currency),
                  profit: formatMoney(row.approx_house_gross_minor, currency),
                })}
              </p>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}

export function PeriodCompareStrip({
  series,
  formatMoney,
  currency,
}: {
  series: AdminReportDailyProfitRow[];
  formatMoney: MoneyFormatter;
  currency: string | null;
}): ReactElement {
  const { t } = useTranslation("dashboard");
  const totalBet = series.reduce((s, d) => s + d.total_bet_minor, 0);
  const totalPayout = series.reduce((s, d) => s + d.total_payout_minor, 0);
  const totalProfit = series.reduce((s, d) => s + d.approx_house_gross_minor, 0);
  const max = Math.max(totalBet, totalPayout, Math.abs(totalProfit), 1);

  const items = [
    { key: "bet", label: t("chartLegend.bet"), value: totalBet, className: "bg-primary" },
    { key: "payout", label: t("chartLegend.payout"), value: totalPayout, className: "bg-rose-500" },
    {
      key: "profit",
      label: t("chartLegend.profit"),
      value: totalProfit,
      className: totalProfit >= 0 ? "bg-emerald-500" : "bg-amber-500",
    },
  ];

  return (
    <div className="grid gap-3 sm:grid-cols-3">
      {items.map((item) => (
        <div key={item.key} className="rounded-lg border border-border/60 bg-muted/20 px-3 py-3">
          <div className="mb-2 flex items-center justify-between gap-2">
            <span className="flex items-center gap-2 text-xs text-muted-foreground">
              <span className={cn("size-2.5 rounded-sm", item.className)} />
              {item.label}
            </span>
            <span className="text-sm font-semibold tabular-nums">{formatMoney(item.value, currency)}</span>
          </div>
          <div className="h-2 overflow-hidden rounded-full bg-muted">
            <div
              className={cn("h-full rounded-full", item.className)}
              style={{ width: `${(Math.abs(item.value) / max) * 100}%` }}
            />
          </div>
        </div>
      ))}
    </div>
  );
}
