"use client";

import { useEffect, useState } from "react";

interface FamilyRow {
  id: string;
  name: string;
  tier: string;
  isPaid: boolean;
  bytes: number;
  memoryCount: number;
  attachmentCount: number;
  objectCount: number;
  fraction: number;
  overLimit: boolean;
}
interface Summary {
  totalBytes: number;
  totalObjects: number;
  familyCount: number;
  paidCount: number;
  freeCount: number;
  overLimitCount: number;
  approachingCount: number;
  estMonthlyCostUsd: number;
  freeLimitBytes: number;
  avgBytesPerFamily: number;
}
interface Data { summary: Summary; families: FamilyRow[]; byDay: { date: string; bytes: number; count: number }[]; error?: string }

const EMPTY: Summary = {
  totalBytes: 0, totalObjects: 0, familyCount: 0, paidCount: 0, freeCount: 0,
  overLimitCount: 0, approachingCount: 0, estMonthlyCostUsd: 0, freeLimitBytes: 1_073_741_824, avgBytesPerFamily: 0,
};

function fmtBytes(n: number): string {
  if (!n) return "0 B";
  const u = ["B", "KB", "MB", "GB", "TB"];
  const i = Math.min(Math.floor(Math.log(n) / Math.log(1024)), u.length - 1);
  return `${(n / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 1)} ${u[i]}`;
}

export default function AdminStorage() {
  const [data, setData] = useState<Data>({ summary: EMPTY, families: [], byDay: [] });
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("/api/admin/storage", { credentials: "include" })
      .then(r => r.json())
      .then(d => {
        setData({
          summary: { ...EMPTY, ...(d?.summary || {}) },
          families: Array.isArray(d?.families) ? d.families : [],
          byDay: Array.isArray(d?.byDay) ? d.byDay : [],
          error: d?.error,
        });
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, []);

  const { summary, families, byDay } = data;
  const maxDayBytes = Math.max(...byDay.map(d => d.bytes), 1);

  return (
    <div className="p-6 space-y-6">
      <div className="flex justify-between items-start flex-wrap gap-3">
        <div>
          <h1 className="text-2xl font-bold">Storage &amp; Billing</h1>
          <p className="text-gray-400">Per-family R2 storage usage — the basis for usage billing</p>
        </div>
      </div>

      {data.error && (
        <div className="bg-rose-500/10 border border-rose-500/30 text-rose-300 text-sm p-3 rounded-lg">
          <span className="font-semibold">Some queries failed:</span> <span className="font-mono break-words">{data.error}</span>
        </div>
      )}

      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <Card label="Total Storage" value={fmtBytes(summary.totalBytes)} color="text-rose-400" sub={`${summary.totalObjects.toLocaleString()} objects`} />
        <Card label="Est. R2 Cost / mo" value={`$${summary.estMonthlyCostUsd.toFixed(2)}`} color="text-amber-400" sub="@ $0.015/GB-mo" />
        <Card label="Avg / Family" value={fmtBytes(summary.avgBytesPerFamily)} color="text-blue-400" sub={`${summary.familyCount} families`} />
        <Card label="Over Free Limit" value={summary.overLimitCount} color={summary.overLimitCount > 0 ? "text-rose-400" : "text-emerald-400"} sub={`${summary.approachingCount} approaching`} />
      </div>

      {/* Daily upload volume */}
      <div className="bg-gray-800 p-6 rounded-xl">
        <h3 className="text-lg font-semibold mb-4">Uploads — last 30 days</h3>
        <div className="h-32 flex items-end gap-1">
          {byDay.length === 0 ? (
            <div className="w-full text-center text-gray-500 text-sm self-center">No uploads in the last 30 days</div>
          ) : byDay.slice(-30).map((d, i) => (
            <div key={i} title={`${d.date}: ${fmtBytes(d.bytes)} · ${d.count} files`} className="flex-1 group">
              <div className="w-full bg-rose-500 group-hover:bg-rose-400 rounded-t" style={{ height: `${Math.max((d.bytes / maxDayBytes) * 100, d.bytes > 0 ? 3 : 0)}%` }} />
            </div>
          ))}
        </div>
      </div>

      {/* Per-family table */}
      <div className="bg-gray-800 rounded-xl overflow-hidden">
        <div className="px-4 py-3 border-b border-gray-700 flex justify-between items-center">
          <h3 className="text-lg font-semibold">By family</h3>
          <span className="text-sm text-gray-500">{summary.paidCount} paid · {summary.freeCount} free</span>
        </div>
        {loading ? (
          <div className="p-8 text-center text-gray-400">Loading…</div>
        ) : families.length === 0 ? (
          <div className="p-8 text-center text-gray-500">No families</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead className="bg-gray-700"><tr>
                <th className="px-4 py-3 text-left text-sm font-medium">Family</th>
                <th className="px-4 py-3 text-left text-sm font-medium">Tier</th>
                <th className="px-4 py-3 text-right text-sm font-medium">Objects</th>
                <th className="px-4 py-3 text-right text-sm font-medium">Storage</th>
                <th className="px-4 py-3 text-left text-sm font-medium w-48">% of free (1 GiB)</th>
              </tr></thead>
              <tbody className="divide-y divide-gray-700">
                {families.map(f => {
                  const pct = Math.min(Math.round(f.fraction * 100), 999);
                  const barColor = f.overLimit ? "bg-rose-500" : f.fraction >= 0.8 ? "bg-amber-500" : "bg-emerald-500";
                  return (
                    <tr key={f.id} className="hover:bg-gray-750">
                      <td className="px-4 py-3 font-medium">{f.name}</td>
                      <td className="px-4 py-3">
                        <span className={`text-xs px-2 py-0.5 rounded font-medium ${f.isPaid ? "bg-rose-500/20 text-rose-400" : "bg-gray-700 text-gray-400"}`}>{f.tier}</span>
                      </td>
                      <td className="px-4 py-3 text-right text-sm text-gray-300">
                        {f.objectCount.toLocaleString()}
                        <span className="text-gray-600 text-xs"> ({f.memoryCount}📸 {f.attachmentCount}📎)</span>
                      </td>
                      <td className="px-4 py-3 text-right text-sm font-medium">{fmtBytes(f.bytes)}</td>
                      <td className="px-4 py-3">
                        {f.isPaid ? (
                          <span className="text-xs text-rose-400">Unlimited (paid)</span>
                        ) : (
                          <div className="flex items-center gap-2">
                            <div className="flex-1 bg-gray-700 rounded-full h-2 overflow-hidden">
                              <div className={`h-full ${barColor}`} style={{ width: `${Math.min(pct, 100)}%` }} />
                            </div>
                            <span className={`text-xs w-12 text-right ${f.overLimit ? "text-rose-400 font-bold" : "text-gray-400"}`}>{pct}%</span>
                          </div>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <p className="text-xs text-gray-600">
        Usage = SUM(size_bytes) over memories + attachments, matching the quota enforced in the app.
        Objects missing a recorded size aren&apos;t counted in bytes. R2 cost is storage only (egress is free on R2).
      </p>
    </div>
  );
}

function Card({ label, value, color, sub }: { label: string; value: string | number; color: string; sub?: string }) {
  return (
    <div className="bg-gray-800 p-4 rounded-xl">
      <div className={`text-2xl font-bold ${color}`}>{value}</div>
      <div className="text-sm text-gray-300 mt-0.5">{label}</div>
      {sub && <div className="text-xs text-gray-500 mt-0.5">{sub}</div>}
    </div>
  );
}
