"use client";

import { useState } from "react";
import useSWR from "swr";
import { Image, RefreshCw, Wand2 } from "lucide-react";
import { toast } from "sonner";
import { apiSend, ApiError, fetcher } from "@/lib/api";
import { PageHeader, StatCard } from "@/components/page-header";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { formatNumber } from "@/lib/utils";

interface Ringkasan {
  jumlah: number;
  ukuran: number;
  folder: string;
}

interface Hasil {
  diproses: number;
  sebelum: number;
  sesudah: number;
  hemat: number;
}

function formatBytes(bytes: number) {
  if (!bytes) return "0 B";
  const units = ["B", "KB", "MB", "GB"];
  const index = Math.min(units.length - 1, Math.floor(Math.log(bytes) / Math.log(1024)));
  return `${(bytes / 1024 ** index).toLocaleString("id-ID", { maximumFractionDigits: 1 })} ${units[index]}`;
}

export default function OptimasiGambarPage() {
  const { data, isLoading, mutate } = useSWR<Ringkasan>("/optimasi-gambar", fetcher);
  const [maxWidth, setMaxWidth] = useState("1600");
  const [quality, setQuality] = useState("82");
  const [running, setRunning] = useState(false);
  const [hasil, setHasil] = useState<Hasil | null>(null);

  async function optimize() {
    setRunning(true);
    try {
      const result = await apiSend<Hasil>("/optimasi-gambar", "POST", {
        maxWidth: Number(maxWidth),
        quality: Number(quality),
      });
      setHasil(result);
      toast.success(`${result.diproses} gambar diperiksa`);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal mengoptimalkan gambar");
    } finally {
      setRunning(false);
    }
  }

  return (
    <div className="space-y-5">
      <PageHeader
        title="Optimasi Gambar"
        description="Perkecil ukuran gambar unggahan agar website lebih cepat."
        action={
          <Button onClick={optimize} disabled={running}>
            {running ? <RefreshCw className="h-4 w-4 animate-spin" /> : <Wand2 className="h-4 w-4" />}
            Optimalkan Sekarang
          </Button>
        }
      />
      <div className="grid gap-4 sm:grid-cols-3">
        <StatCard title="Berkas Unggahan" value={formatNumber(data?.jumlah ?? 0)} icon={Image} />
        <StatCard title="Total Ukuran" value={formatBytes(data?.ukuran ?? 0)} icon={Image} tone="sky" />
        <StatCard
          title="Hemat Terakhir"
          value={hasil ? formatBytes(hasil.hemat) : "-"}
          hint={hasil ? `${hasil.diproses} gambar diperiksa` : "Belum dijalankan"}
          icon={Image}
          tone="amber"
        />
      </div>
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Pengaturan Optimasi</CardTitle>
          <CardDescription>Lebar maksimum dan kualitas kompresi gambar.</CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-1.5">
            <Label htmlFor="max-width">Lebar Maksimum (px)</Label>
            <Input
              id="max-width"
              type="number"
              value={maxWidth}
              onChange={(event) => setMaxWidth(event.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="quality">Kualitas (30–100)</Label>
            <Input
              id="quality"
              type="number"
              value={quality}
              onChange={(event) => setQuality(event.target.value)}
            />
          </div>
          <p className="text-xs text-muted-foreground sm:col-span-2">
            Folder dipindai: <span className="font-mono">{data?.folder ?? "uploads"}</span>. Gambar hanya
            ditimpa bila hasil kompresi lebih kecil.
          </p>
          {isLoading && <p className="text-xs text-muted-foreground">Memuat ringkasan unggahan…</p>}
        </CardContent>
      </Card>
    </div>
  );
}
