// @File: src/pages/admin/cms/CmsVisitorReports.tsx
// @Desc: Charts + CSV export. Uses recharts (already in deps).
import { useCallback, useEffect, useMemo, useState } from "react";
import {
  BarChart,
  Bar,
  CartesianGrid,
  Cell,
  Legend,
  Line,
  LineChart,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { BarChart3, Download, Loader2, RefreshCw } from "lucide-react";
import CmsLayout from "./CmsLayout";
import { Field, PageHeader, SectionCard, Select, TextInput } from "./ui";
import { vmGetReport, type VmBucket, type VmReport } from "@/lib/adminApi";

const COLORS = [
  "#0b6e3e",
  "#0a8048",
  "#1e88e5",
  "#7e57c2",
  "#ef6c00",
  "#c2185b",
  "#00897b",
  "#5d4037",
  "#f9a825",
  "#546e7a",
];

function toCsv(rows: (string | number)[][]): string {
  return rows
    .map((r) =>
      r
        .map((v) => {
          const s = String(v ?? "");
          if (s.includes(",") || s.includes("\n") || s.includes('"')) {
            return `"${s.replace(/"/g, '""')}"`;
          }
          return s;
        })
        .join(","),
    )
    .join("\n");
}

function downloadCsv(name: string, rows: (string | number)[][]) {
  const blob = new Blob([toCsv(rows)], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = name;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

export default function CmsVisitorReports() {
  const [data, setData] = useState<VmReport | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [start, setStart] = useState("");
  const [end, setEnd] = useState("");
  const [campaign, setCampaign] = useState("");
  const [source, setSource] = useState("");
  const [country, setCountry] = useState("");
  const [device, setDevice] = useState("");

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await vmGetReport({
        start: start ? new Date(`${start}T00:00:00`).toISOString() : undefined,
        end: end ? new Date(`${end}T23:59:59`).toISOString() : undefined,
        campaign: campaign || undefined,
        source: source || undefined,
        country: country || undefined,
        device: device || undefined,
      });
      setData(res);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load report");
    } finally {
      setLoading(false);
    }
  }, [start, end, campaign, source, country, device]);

  useEffect(() => {
    void load();
  }, [load]);

  const byDay = useMemo(
    () =>
      (data?.by_day ?? []).map((d) => ({
        date: d.date,
        visits: d.visits,
        uniques: d.unique_visitors,
      })),
    [data],
  );

  const exportAll = () => {
    if (!data) return;
    const rows: (string | number)[][] = [["section", "key", "count"]];
    const push = (section: string, buckets: VmBucket[]) => {
      buckets.forEach((b) => rows.push([section, b.key, b.count]));
    };
    data.by_day.forEach((d) =>
      rows.push(["by_day", d.date, `${d.visits}/${d.unique_visitors}`]),
    );
    push("by_source", data.by_source);
    push("by_campaign", data.by_campaign);
    push("by_device", data.by_device);
    push("by_browser", data.by_browser);
    push("by_country", data.by_country);
    downloadCsv(`visitor-report-${Date.now()}.csv`, rows);
  };

  return (
    <CmsLayout>
      <PageHeader
        title="Reports"
        description="Traffic by day, source, campaign, device, browser and country."
        icon={<BarChart3 className="w-6 h-6" />}
      />

      <SectionCard
        title="Filters"
        actions={
          <div className="flex items-center gap-2">
            <button
              onClick={() => void load()}
              className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border border-slate-300 bg-white text-sm font-semibold text-slate-700 hover:bg-slate-50 transition"
            >
              {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <RefreshCw className="w-4 h-4" />}
              Apply
            </button>
            <button
              onClick={exportAll}
              className="inline-flex items-center gap-2 px-3 py-2 rounded-lg bg-[#0b6e3e] text-white text-sm font-bold hover:bg-[#0a8048] transition"
            >
              <Download className="w-4 h-4" />
              Export CSV
            </button>
          </div>
        }
      >
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <Field label="Start date">
            <TextInput type="date" value={start} onChange={(e) => setStart(e.target.value)} />
          </Field>
          <Field label="End date">
            <TextInput type="date" value={end} onChange={(e) => setEnd(e.target.value)} />
          </Field>
          <Field label="Campaign">
            <TextInput value={campaign} onChange={(e) => setCampaign(e.target.value)} placeholder="cloud-hosting" />
          </Field>
          <Field label="Source">
            <TextInput value={source} onChange={(e) => setSource(e.target.value)} placeholder="facebook" />
          </Field>
          <Field label="Country">
            <TextInput value={country} onChange={(e) => setCountry(e.target.value)} placeholder="United States" />
          </Field>
          <Field label="Device">
            <Select value={device} onChange={(e) => setDevice(e.target.value)}>
              <option value="">Any device</option>
              <option value="desktop">Desktop</option>
              <option value="mobile">Mobile</option>
              <option value="tablet">Tablet</option>
              <option value="bot">Bot</option>
            </Select>
          </Field>
        </div>

        {error && (
          <div className="p-3 rounded-lg bg-red-50 border border-red-200 text-sm text-red-700">
            {error}
          </div>
        )}
      </SectionCard>

      <div className="grid grid-cols-1 gap-6 mt-6">
        <SectionCard title="Visits by day">
          <div className="h-72">
            {byDay.length === 0 ? (
              <div className="h-full flex items-center justify-center text-slate-400 text-sm">
                No data in this range.
              </div>
            ) : (
              <ResponsiveContainer width="100%" height="100%">
                <LineChart data={byDay}>
                  <CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
                  <XAxis dataKey="date" fontSize={11} />
                  <YAxis fontSize={11} allowDecimals={false} />
                  <Tooltip />
                  <Legend />
                  <Line type="monotone" dataKey="visits" stroke="#0b6e3e" strokeWidth={2} />
                  <Line type="monotone" dataKey="uniques" stroke="#1e88e5" strokeWidth={2} />
                </LineChart>
              </ResponsiveContainer>
            )}
          </div>
        </SectionCard>

        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <SectionCard title="Traffic source">
            <BucketBarChart data={data?.by_source ?? []} />
          </SectionCard>
          <SectionCard title="Campaign performance">
            <BucketBarChart data={data?.by_campaign ?? []} />
          </SectionCard>
          <SectionCard title="Device">
            <BucketPieChart data={data?.by_device ?? []} />
          </SectionCard>
          <SectionCard title="Browser">
            <BucketPieChart data={data?.by_browser ?? []} />
          </SectionCard>
          <SectionCard title="Country">
            <BucketBarChart data={data?.by_country ?? []} />
          </SectionCard>
        </div>
      </div>
    </CmsLayout>
  );
}

function BucketBarChart({ data }: { data: VmBucket[] }) {
  if (data.length === 0) {
    return (
      <div className="h-60 flex items-center justify-center text-slate-400 text-sm">
        No data.
      </div>
    );
  }
  return (
    <div className="h-60">
      <ResponsiveContainer width="100%" height="100%">
        <BarChart data={data}>
          <CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
          <XAxis dataKey="key" fontSize={10} interval={0} angle={-20} height={50} />
          <YAxis fontSize={11} allowDecimals={false} />
          <Tooltip />
          <Bar dataKey="count" fill="#0b6e3e" radius={[6, 6, 0, 0]} />
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}

function BucketPieChart({ data }: { data: VmBucket[] }) {
  if (data.length === 0) {
    return (
      <div className="h-60 flex items-center justify-center text-slate-400 text-sm">
        No data.
      </div>
    );
  }
  return (
    <div className="h-60">
      <ResponsiveContainer width="100%" height="100%">
        <PieChart>
          <Pie
            data={data}
            dataKey="count"
            nameKey="key"
            innerRadius={40}
            outerRadius={80}
            paddingAngle={2}
          >
            {data.map((_, i) => (
              <Cell key={i} fill={COLORS[i % COLORS.length]} />
            ))}
          </Pie>
          <Tooltip />
          <Legend wrapperStyle={{ fontSize: 11 }} />
        </PieChart>
      </ResponsiveContainer>
    </div>
  );
}