"use client";

import type { ReactNode } from "react";
import { useEffect, useState } from "react";
import { BarChart3, CalendarRange, RefreshCcw, Users } from "lucide-react";

import type { StatisticsRangePreset, StatsResponse } from "@rental/shared";

import { getStatsRequest } from "../../lib/api";
import { useSessionContext } from "../layout/session-provider";
import { Badge } from "../ui/badge";
import { Button } from "../ui/button";
import { Card } from "../ui/card";
import { Input } from "../ui/input";

const today = () => new Date().toISOString().slice(0, 10);

const getMonthRange = (date: string) => {
  const start = `${date.slice(0, 7)}-01`;
  const nextMonth = new Date(`${start}T12:00:00.000Z`);
  nextMonth.setUTCMonth(nextMonth.getUTCMonth() + 1);
  nextMonth.setUTCDate(0);

  return {
    from: start,
    to: nextMonth.toISOString().slice(0, 10)
  };
};

const getYearRange = (date: string) => ({
  from: `${date.slice(0, 4)}-01-01`,
  to: `${date.slice(0, 4)}-12-31`
});

const currency = (value: number) =>
  new Intl.NumberFormat("pl-PL", {
    style: "currency",
    currency: "PLN",
    maximumFractionDigits: 2
  }).format(value);

const StatTable = ({
  columns,
  rows
}: {
  columns: string[];
  rows: Array<Array<ReactNode>>;
}) => (
  <div className="overflow-x-auto rounded-[18px] border border-line">
    <table className="min-w-full divide-y divide-line text-sm">
      <thead className="bg-[#f5efe5] text-left text-[11px] font-semibold uppercase tracking-[0.14em] text-muted">
        <tr>
          {columns.map((column) => (
            <th key={column} className="px-3 py-2.5">
              {column}
            </th>
          ))}
        </tr>
      </thead>
      <tbody className="divide-y divide-line/70 bg-white">
        {rows.length > 0 ? (
          rows.map((row, rowIndex) => (
            <tr key={`row-${rowIndex}`}>
              {row.map((cell, cellIndex) => (
                <td key={`cell-${rowIndex}-${cellIndex}`} className="px-3 py-2.5 align-top text-ink">
                  {cell}
                </td>
              ))}
            </tr>
          ))
        ) : (
          <tr>
            <td className="px-3 py-5 text-sm text-muted" colSpan={columns.length}>
              Brak danych dla wybranego zakresu.
            </td>
          </tr>
        )}
      </tbody>
    </table>
  </div>
);

export const AdminStatsPage = () => {
  const { session } = useSessionContext();
  const isAdmin = session?.user.role === "admin";
  const defaultMonthRange = getMonthRange(today());

  const [preset, setPreset] = useState<StatisticsRangePreset>("month");
  const [from, setFrom] = useState(defaultMonthRange.from);
  const [to, setTo] = useState(defaultMonthRange.to);
  const [stats, setStats] = useState<StatsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const refresh = async (nextFrom = from, nextTo = to) => {
    if (!session || !isAdmin) {
      return;
    }

    setLoading(true);
    setError(null);

    try {
      const data = await getStatsRequest(session, {
        from: nextFrom,
        to: nextTo
      });
      setStats(data);
    } catch (requestError) {
      setError(requestError instanceof Error ? requestError.message : "Nie udało się pobrać statystyk");
    } finally {
      setLoading(false);
    }
  };

  const applyPreset = (nextPreset: StatisticsRangePreset) => {
    const baseDate = today();
    const nextRange = nextPreset === "year" ? getYearRange(baseDate) : getMonthRange(baseDate);

    setPreset(nextPreset);

    if (nextPreset !== "custom") {
      setFrom(nextRange.from);
      setTo(nextRange.to);
      void refresh(nextRange.from, nextRange.to);
    }
  };

  useEffect(() => {
    if (!session || !isAdmin) {
      setLoading(false);
      return;
    }

    void refresh(defaultMonthRange.from, defaultMonthRange.to);
  }, [isAdmin, session]);

  if (!isAdmin) {
    return (
      <Card className="p-5">
        <p className="text-sm text-muted">Statystyki są dostępne tylko dla administratora.</p>
      </Card>
    );
  }

  return (
    <div className="space-y-5">
      <Card className="p-4">
        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div>
            <div className="flex items-center gap-2">
              <Badge tone="accent">Statystyki</Badge>
            </div>
            <h2 className="mt-2 text-2xl font-semibold text-ink">Przychód i aktywność systemu</h2>
          </div>

          <div className="flex flex-wrap gap-2">
            <Button variant={preset === "month" ? "primary" : "secondary"} onClick={() => applyPreset("month")}>
              Miesiąc
            </Button>
            <Button variant={preset === "year" ? "primary" : "secondary"} onClick={() => applyPreset("year")}>
              Rok
            </Button>
            <Button variant={preset === "custom" ? "primary" : "secondary"} onClick={() => setPreset("custom")}>
              Zakres dni
            </Button>
          </div>
        </div>
      </Card>

      <Card className="p-4 sm:p-5">
        <div className="grid gap-3 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]">
          <label className="block space-y-2">
            <span className="text-sm font-medium text-ink">Data od</span>
            <Input type="date" value={from} onChange={(event) => setFrom(event.target.value)} />
          </label>
          <label className="block space-y-2">
            <span className="text-sm font-medium text-ink">Data do</span>
            <Input type="date" value={to} onChange={(event) => setTo(event.target.value)} />
          </label>
          <div className="flex items-end">
            <Button className="w-full lg:w-auto" variant="secondary" onClick={() => void refresh()}>
              <RefreshCcw className="h-4 w-4" />
              Odśwież
            </Button>
          </div>
        </div>

        {error ? <p className="mt-4 rounded-2xl bg-[#f8d9d3] px-4 py-3 text-sm text-[#8d2f20]">{error}</p> : null}
      </Card>

      <div className="grid gap-4 lg:grid-cols-4">
        <Card className="p-4">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-xs uppercase tracking-[0.18em] text-muted">Przychód</p>
              <p className="mt-2 text-2xl font-semibold text-ink">{currency(stats?.totalRevenue ?? 0)}</p>
            </div>
            <BarChart3 className="h-5 w-5 text-accent" />
          </div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-xs uppercase tracking-[0.18em] text-muted">Produkty</p>
              <p className="mt-2 text-2xl font-semibold text-ink">{stats?.revenueByProduct.length ?? 0}</p>
            </div>
            <CalendarRange className="h-5 w-5 text-accent" />
          </div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-xs uppercase tracking-[0.18em] text-muted">Klienci</p>
              <p className="mt-2 text-2xl font-semibold text-ink">{stats?.revenueByCustomer.length ?? 0}</p>
            </div>
            <Users className="h-5 w-5 text-accent" />
          </div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-xs uppercase tracking-[0.18em] text-muted">Kliknięcia</p>
              <p className="mt-2 text-2xl font-semibold text-ink">
                {stats?.userClicks.reduce((sum, row) => sum + row.clickCount, 0) ?? 0}
              </p>
            </div>
            <Badge tone="neutral">{from} - {to}</Badge>
          </div>
        </Card>
      </div>

      <div className="grid gap-5 xl:grid-cols-2">
        <Card className="p-4 sm:p-5">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-xs uppercase tracking-[0.18em] text-muted">Produkty</p>
              <h3 className="mt-1 text-lg font-semibold text-ink">Przychód per produkt</h3>
            </div>
            {loading ? <Badge tone="neutral">Ładowanie</Badge> : <Badge tone="success">Lifetime w tabeli</Badge>}
          </div>

          <div className="mt-4">
            <StatTable
              columns={["Produkt", "Grupa", "Rezerwacje", "Przychód", "Lifetime"]}
              rows={(stats?.revenueByProduct ?? []).map((row) => [
                <div key={`${row.productKey}-name`} className="min-w-[160px]">
                  <p className="font-semibold text-ink">{row.productShortName || row.productName}</p>
                  {row.productShortName ? <p className="text-xs text-muted">{row.productName}</p> : null}
                </div>,
                row.categoryName,
                row.bookingCount,
                currency(row.revenue),
                currency(row.lifetimeRevenue)
              ])}
            />
          </div>
        </Card>

        <Card className="p-4 sm:p-5">
          <div>
            <p className="text-xs uppercase tracking-[0.18em] text-muted">Grupy</p>
            <h3 className="mt-1 text-lg font-semibold text-ink">Przychód per grupa produktów</h3>
          </div>

          <div className="mt-4">
            <StatTable
              columns={["Grupa", "Rezerwacje", "Przychód", "Lifetime"]}
              rows={(stats?.revenueByCategory ?? []).map((row) => [
                row.categoryName,
                row.bookingCount,
                currency(row.revenue),
                currency(row.lifetimeRevenue)
              ])}
            />
          </div>
        </Card>
      </div>

      <div className="grid gap-5 xl:grid-cols-2">
        <Card className="p-4 sm:p-5">
          <div>
            <p className="text-xs uppercase tracking-[0.18em] text-muted">Klienci</p>
            <h3 className="mt-1 text-lg font-semibold text-ink">Przychód per klient</h3>
          </div>

          <div className="mt-4">
            <StatTable
              columns={["Klient", "Rezerwacje", "Przychód"]}
              rows={(stats?.revenueByCustomer ?? []).map((row) => [row.customerName, row.bookingCount, currency(row.revenue)])}
            />
          </div>
        </Card>

        <Card className="p-4 sm:p-5">
          <div>
            <p className="text-xs uppercase tracking-[0.18em] text-muted">Aktywność</p>
            <h3 className="mt-1 text-lg font-semibold text-ink">Kliknięcia użytkowników dziennie</h3>
          </div>

          <div className="mt-4">
            <StatTable
              columns={["Data", "Użytkownik", "Kliknięcia"]}
              rows={(stats?.userClicks ?? []).map((row) => [row.clickDate, row.userName, row.clickCount])}
            />
          </div>
        </Card>
      </div>
    </div>
  );
};
