"use client";

import * as React from "react";
import { toast } from "sonner";
import { useTheme } from "next-themes";
import {
  Loader2,
  Save,
  Sun,
  Moon,
  Monitor,
  Bell,
  HardDrive,
  Trash2,
  RefreshCw,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";

const NOTIFICATION_STORAGE_KEY = "echo-ocr-notification-prefs";

type NotificationPrefs = {
  processingComplete: boolean;
  processingErrors: boolean;
  folderWatchAlerts: boolean;
  cleanupReminders: boolean;
};

const DEFAULT_NOTIFICATION_PREFS: NotificationPrefs = {
  processingComplete: true,
  processingErrors: true,
  folderWatchAlerts: true,
  cleanupReminders: false,
};

function loadNotificationPrefs(): NotificationPrefs {
  if (typeof window === "undefined") return DEFAULT_NOTIFICATION_PREFS;
  try {
    const raw = localStorage.getItem(NOTIFICATION_STORAGE_KEY);
    if (raw) return { ...DEFAULT_NOTIFICATION_PREFS, ...JSON.parse(raw) };
  } catch {}
  return DEFAULT_NOTIFICATION_PREFS;
}

export default function GeneralSettingsPage() {
  const { theme, setTheme } = useTheme();
  const [sourceRetention, setSourceRetention] = React.useState(30);
  const [imageRetention, setImageRetention] = React.useState(180);
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [cleanupStatus, setCleanupStatus] = React.useState<{
    sourcesEligible: number;
    imagesEligible: number;
  } | null>(null);
  const [cleaning, setCleaning] = React.useState(false);
  const [fetchError, setFetchError] = React.useState(false);
  const [notifPrefs, setNotifPrefs] = React.useState<NotificationPrefs>(
    DEFAULT_NOTIFICATION_PREFS
  );

  React.useEffect(() => {
    setNotifPrefs(loadNotificationPrefs());
  }, []);

  React.useEffect(() => {
    fetch("/api/settings")
      .then((r) => r.json())
      .then((data) => {
        setSourceRetention(data.sourceRetentionDays || 30);
        setImageRetention(data.imageRetentionDays || 180);
        setLoading(false);
      })
      .catch(() => {
        setFetchError(true);
        toast.error("Failed to load settings");
        setLoading(false);
      });

    fetch("/api/cleanup")
      .then((r) => r.json())
      .then((data) => {
        if (data.sourcesEligible !== undefined) setCleanupStatus(data);
      })
      .catch(() => {
        toast.error("Failed to load cleanup status");
      });
  }, []);

  const updateNotifPref = (key: keyof NotificationPrefs, value: boolean) => {
    setNotifPrefs((prev) => {
      const next = { ...prev, [key]: value };
      try {
        localStorage.setItem(NOTIFICATION_STORAGE_KEY, JSON.stringify(next));
      } catch {}
      return next;
    });
    toast.success("Notification preference updated");
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      const res = await fetch("/api/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          sourceRetentionDays: sourceRetention,
          imageRetentionDays: imageRetention,
        }),
      });
      if (!res.ok) throw new Error();
      toast.success("Settings saved");
    } catch {
      toast.error("Failed to save settings");
    } finally {
      setSaving(false);
    }
  };

  const runCleanup = async () => {
    setCleaning(true);
    try {
      const res = await fetch("/api/cleanup", { method: "POST" });
      if (res.ok) {
        const data = await res.json();
        toast.success(
          `Cleaned ${data.sourcesDeleted ?? 0} sources and ${data.imagesDeleted ?? 0} images`
        );
        setCleanupStatus({ sourcesEligible: 0, imagesEligible: 0 });
      }
    } catch {
      toast.error("Cleanup failed");
    } finally {
      setCleaning(false);
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="size-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Appearance */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Sun className="size-4" />
            Appearance
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex gap-2">
            {[
              { value: "light", icon: Sun, label: "Light" },
              { value: "dark", icon: Moon, label: "Dark" },
              { value: "system", icon: Monitor, label: "System" },
            ].map((opt) => (
              <Button
                key={opt.value}
                variant={theme === opt.value ? "default" : "outline"}
                size="sm"
                onClick={() => setTheme(opt.value)}
                className="gap-1.5"
              >
                <opt.icon className="size-3.5" />
                {opt.label}
              </Button>
            ))}
          </div>
        </CardContent>
      </Card>

      {/* Notifications */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Bell className="size-4" />
            Notifications
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          {(
            [
              ["processingComplete", "Processing Complete"],
              ["processingErrors", "Processing Errors"],
              ["folderWatchAlerts", "Folder Watch Alerts"],
              ["cleanupReminders", "Cleanup Reminders"],
            ] as const
          ).map(([key, label]) => (
            <div key={key} className="flex items-center justify-between">
              <Label className="text-sm">{label}</Label>
              <Switch
                checked={notifPrefs[key]}
                onCheckedChange={(v) => updateNotifPref(key, v)}
              />
            </div>
          ))}
        </CardContent>
      </Card>

      {/* Storage & Retention */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <HardDrive className="size-4" />
            Storage & Retention
          </CardTitle>
          <CardDescription>
            Automatically clean up old files to save storage.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>Source file retention (days)</Label>
              <Input
                type="number"
                min={1}
                value={sourceRetention}
                onChange={(e) =>
                  setSourceRetention(parseInt(e.target.value) || 30)
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Image retention (days)</Label>
              <Input
                type="number"
                min={1}
                value={imageRetention}
                onChange={(e) =>
                  setImageRetention(parseInt(e.target.value) || 180)
                }
              />
            </div>
          </div>
          {cleanupStatus && (
            <div className="flex items-center gap-4 text-sm text-muted-foreground">
              <span>
                {cleanupStatus.sourcesEligible} sources,{" "}
                {cleanupStatus.imagesEligible} images eligible for cleanup
              </span>
              <Button
                variant="outline"
                size="sm"
                onClick={runCleanup}
                disabled={cleaning}
              >
                {cleaning ? (
                  <Loader2 className="mr-1.5 size-3.5 animate-spin" />
                ) : (
                  <Trash2 className="mr-1.5 size-3.5" />
                )}
                Run Cleanup
              </Button>
            </div>
          )}
        </CardContent>
      </Card>

      <div className="flex items-center justify-end gap-3">
        {fetchError && (
          <p className="text-sm text-destructive">Settings failed to load — saving is disabled</p>
        )}
        <Button onClick={handleSave} disabled={saving || fetchError}>
          {saving ? (
            <Loader2 className="mr-2 size-4 animate-spin" />
          ) : (
            <Save className="mr-2 size-4" />
          )}
          Save Changes
        </Button>
      </div>
    </div>
  );
}
