"use client";

import { useEffect, useState, useCallback } from "react";
import { Loader2, Save } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

interface SettingsFormProps {
  title: string;
  description?: string;
  fields: Array<{
    key: string;
    label: string;
    type?: "text" | "textarea" | "color" | "select" | "number" | "switch";
    options?: Array<{ value: string; label: string }>;
    placeholder?: string;
  }>;
  includeUpload?: Array<{ type: string; label: string; field: string }>;
}

export function SettingsForm({ title, description, fields, includeUpload }: SettingsFormProps) {
  const [settings, setSettings] = useState<Record<string, unknown>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState("");

  const fetchSettings = useCallback(async () => {
    const res = await fetch("/api/admin/settings");
    const data = await res.json();
    setSettings(data);
    setLoading(false);
  }, []);

  useEffect(() => {
    fetchSettings();
  }, [fetchSettings]);

  const handleSave = async () => {
    setSaving(true);
    setMessage("");
    try {
      const res = await fetch("/api/admin/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(settings),
      });
      if (!res.ok) throw new Error("Failed to save");
      setMessage("Saved successfully!");
    } catch {
      setMessage("Failed to save. Please try again.");
    }
    setSaving(false);
  };

  const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>, type: string, field: string) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const formData = new FormData();
    formData.append("file", file);
    formData.append("type", type);

    const res = await fetch("/api/admin/upload", { method: "POST", body: formData });
    const data = await res.json();
    if (data.url) {
      setSettings((prev) => ({ ...prev, [field]: data.url }));
    }
  };

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

  return (
    <div className="space-y-6 max-w-3xl">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold">{title}</h1>
          {description && <p className="text-muted-foreground">{description}</p>}
        </div>
        <Button onClick={handleSave} disabled={saving}>
          {saving ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : <Save className="h-4 w-4 mr-2" />}
          Save Changes
        </Button>
      </div>

      {message && (
        <p className={`text-sm ${message.includes("success") ? "text-accent" : "text-destructive"}`}>
          {message}
        </p>
      )}

      {includeUpload && (
        <Card>
          <CardHeader><CardTitle>Uploads</CardTitle></CardHeader>
          <CardContent className="space-y-4">
            {includeUpload.map(({ type, label, field }) => (
              <div key={type}>
                <Label>{label}</Label>
                {settings[field] ? (
                  <p className="text-sm text-muted-foreground mb-2">Current: {String(settings[field])}</p>
                ) : null}
                <Input type="file" accept="image/*" onChange={(e) => handleUpload(e, type, field)} />
              </div>
            ))}
          </CardContent>
        </Card>
      )}

      <Card>
        <CardContent className="pt-6 space-y-4">
          {fields.map(({ key, label, type = "text", options, placeholder }) => (
            <div key={key}>
              <Label htmlFor={key}>{label}</Label>
              {type === "textarea" ? (
                <Textarea
                  id={key}
                  value={String(settings[key] ?? "")}
                  onChange={(e) => setSettings((prev) => ({ ...prev, [key]: e.target.value }))}
                  placeholder={placeholder}
                  rows={3}
                />
              ) : type === "select" && options ? (
                <Select
                  value={String(settings[key] ?? "")}
                  onValueChange={(v) => setSettings((prev) => ({ ...prev, [key]: v }))}
                >
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>
                    {options.map((o) => (
                      <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              ) : type === "color" ? (
                <div className="flex gap-2">
                  <Input
                    id={key}
                    value={String(settings[key] ?? "")}
                    onChange={(e) => setSettings((prev) => ({ ...prev, [key]: e.target.value }))}
                    placeholder="210 100% 40%"
                  />
                  <div
                    className="w-11 h-11 rounded-md border shrink-0"
                    style={{ backgroundColor: `hsl(${settings[key]})` }}
                  />
                </div>
              ) : (
                <Input
                  id={key}
                  type={type === "number" ? "number" : "text"}
                  value={String(settings[key] ?? "")}
                  onChange={(e) =>
                    setSettings((prev) => ({
                      ...prev,
                      [key]: type === "number" ? Number(e.target.value) : e.target.value,
                    }))
                  }
                  placeholder={placeholder}
                />
              )}
            </div>
          ))}
        </CardContent>
      </Card>
    </div>
  );
}
