"use client";

import { useEffect, useRef, useState } from "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 { Switch } from "@/components/ui/switch";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { toast } from "sonner";
import { Trash2, Upload, Copy, ExternalLink } from "lucide-react";

type SiteSettings = {
  grayscale: boolean;
  shutdownBannerEnabled: boolean;
  shutdownTitle: string;
  shutdownTitleEn: string;
  shutdownSubtitle: string;
  shutdownSubtitleEn: string;
  shutdownAt: string | null;
  bgmUrl: string;
  bgmAutoplay: boolean;
  bgmVolume: number;
};

function toDatetimeLocal(iso: string | null): string {
  if (!iso) return "";
  const d = new Date(iso);
  if (isNaN(d.getTime())) return "";
  const pad = (n: number) => n.toString().padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(
    d.getHours()
  )}:${pad(d.getMinutes())}`;
}

export default function SettingsPage() {
  const [loading, setLoading] = useState(false);
  const [launcherUrl, setLauncherUrl] = useState("");

  useEffect(() => {
    if (typeof window !== "undefined") {
      setLauncherUrl(`${window.location.origin}/download/launcher`);
    }
  }, []);

  async function handleCopyLauncherUrl() {
    try {
      await navigator.clipboard.writeText(launcherUrl);
      toast.success("已复制到剪贴板");
    } catch {
      toast.error("复制失败");
    }
  }

  const [siteLoading, setSiteLoading] = useState(true);
  const [siteSaving, setSiteSaving] = useState(false);
  const [grayscale, setGrayscale] = useState(false);
  const [bannerEnabled, setBannerEnabled] = useState(false);
  const [title, setTitle] = useState("");
  const [titleEn, setTitleEn] = useState("");
  const [subtitle, setSubtitle] = useState("");
  const [subtitleEn, setSubtitleEn] = useState("");
  const [shutdownAtLocal, setShutdownAtLocal] = useState("");
  const [bgmUrl, setBgmUrl] = useState("");
  const [bgmAutoplay, setBgmAutoplay] = useState(false);
  const [bgmVolume, setBgmVolume] = useState(50);
  const [bgmUploading, setBgmUploading] = useState(false);
  const bgmFileRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    (async () => {
      try {
        const res = await fetch("/api/admin/site-settings");
        if (!res.ok) throw new Error();
        const data: SiteSettings = await res.json();
        setGrayscale(data.grayscale);
        setBannerEnabled(data.shutdownBannerEnabled);
        setTitle(data.shutdownTitle);
        setTitleEn(data.shutdownTitleEn ?? "");
        setSubtitle(data.shutdownSubtitle);
        setSubtitleEn(data.shutdownSubtitleEn ?? "");
        setShutdownAtLocal(toDatetimeLocal(data.shutdownAt));
        setBgmUrl(data.bgmUrl || "");
        setBgmAutoplay(!!data.bgmAutoplay);
        setBgmVolume(
          typeof data.bgmVolume === "number" ? data.bgmVolume : 50
        );
      } catch {
        toast.error("加载站点设置失败");
      } finally {
        setSiteLoading(false);
      }
    })();
  }, []);

  async function handleSiteSave(e: React.FormEvent) {
    e.preventDefault();
    setSiteSaving(true);
    const payload = {
      grayscale,
      shutdownBannerEnabled: bannerEnabled,
      shutdownTitle: title,
      shutdownTitleEn: titleEn,
      shutdownSubtitle: subtitle,
      shutdownSubtitleEn: subtitleEn,
      shutdownAt: shutdownAtLocal
        ? new Date(shutdownAtLocal).toISOString()
        : null,
      bgmUrl,
      bgmAutoplay,
      bgmVolume,
    };
    const res = await fetch("/api/admin/site-settings", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    if (res.ok) {
      toast.success("站点设置已保存");
    } else {
      const data = await res.json().catch(() => ({}));
      toast.error(data?.error || "保存失败");
    }
    setSiteSaving(false);
  }

  async function handleBgmUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    if (!file.type.startsWith("audio/")) {
      toast.error("请选择音频文件");
      return;
    }
    setBgmUploading(true);
    try {
      const form = new FormData();
      form.append("file", file);
      const res = await fetch("/api/upload", { method: "POST", body: form });
      if (!res.ok) throw new Error();
      const data = await res.json();
      setBgmUrl(data.filePath as string);
      toast.success("音频上传成功，请记得保存");
    } catch {
      toast.error("音频上传失败");
    } finally {
      setBgmUploading(false);
      if (bgmFileRef.current) bgmFileRef.current.value = "";
    }
  }

  async function handlePasswordSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setLoading(true);

    const formData = new FormData(e.currentTarget);
    const newPassword = formData.get("newPassword") as string;
    const confirmPassword = formData.get("confirmPassword") as string;

    if (newPassword !== confirmPassword) {
      toast.error("两次输入的新密码不一致");
      setLoading(false);
      return;
    }

    const res = await fetch("/api/admin/change-password", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        currentPassword: formData.get("currentPassword"),
        newPassword,
      }),
    });

    const data = await res.json();
    if (res.ok) {
      toast.success("密码修改成功");
      (e.target as HTMLFormElement).reset();
    } else {
      toast.error(data.error || "修改失败");
    }

    setLoading(false);
  }

  return (
    <div className="mx-auto max-w-2xl space-y-6">
      <h1 className="text-3xl font-bold">系统设置</h1>

      <Card>
        <CardHeader>
          <CardTitle>站点外观</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSiteSave} className="space-y-6">
            <div className="flex items-start justify-between gap-4 rounded-lg border p-4">
              <div className="space-y-1">
                <Label className="text-base">全站灰色模式</Label>
                <p className="text-xs text-muted-foreground">
                  启用后前台整站将置为黑白灰，适用于重大纪念或肃穆场合。
                </p>
              </div>
              <Switch
                checked={grayscale}
                onCheckedChange={setGrayscale}
                disabled={siteLoading}
              />
            </div>

            <div className="space-y-4 rounded-lg border p-4">
              <div className="flex items-start justify-between gap-4">
                <div className="space-y-1">
                  <Label className="text-base">关服倒计时 Banner</Label>
                  <p className="text-xs text-muted-foreground">
                    在首页顶部显示倒计时横幅，整体为肃穆风格。
                  </p>
                </div>
                <Switch
                  checked={bannerEnabled}
                  onCheckedChange={setBannerEnabled}
                  disabled={siteLoading}
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="shutdownTitle">标题（中文）</Label>
                <Textarea
                  id="shutdownTitle"
                  value={title}
                  onChange={(e) => setTitle(e.target.value)}
                  rows={2}
                  placeholder={"例如：旅程即将终结\n再见，乌龟服"}
                  disabled={siteLoading}
                />
                <p className="text-xs text-muted-foreground">
                  支持 Markdown：回车即换行，可用 <code>**粗体**</code>、<code>*斜体*</code>、<code>[链接](https://...)</code>。
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="shutdownTitleEn">Title (English)</Label>
                <Textarea
                  id="shutdownTitleEn"
                  value={titleEn}
                  onChange={(e) => setTitleEn(e.target.value)}
                  rows={2}
                  placeholder={"e.g. Every journey ends,\nbut our story carries on"}
                  disabled={siteLoading}
                />
                <p className="text-xs text-muted-foreground">
                  英文用户访问时显示；为空则回退到中文。
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="shutdownSubtitle">副标题 / 简短说明（中文）</Label>
                <Textarea
                  id="shutdownSubtitle"
                  value={subtitle}
                  onChange={(e) => setSubtitle(e.target.value)}
                  rows={4}
                  placeholder="例如：《Turtle WoW》即将关闭，服务器将于欧洲时间 5月15日 凌晨 00:00 正式关闭。"
                  disabled={siteLoading}
                />
                <p className="text-xs text-muted-foreground">
                  支持 Markdown，回车即换行；空行分段。
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="shutdownSubtitleEn">Subtitle (English)</Label>
                <Textarea
                  id="shutdownSubtitleEn"
                  value={subtitleEn}
                  onChange={(e) => setSubtitleEn(e.target.value)}
                  rows={4}
                  placeholder="e.g. Turtle WoW will be shutting down. Servers go offline at midnight European time on May 15."
                  disabled={siteLoading}
                />
                <p className="text-xs text-muted-foreground">
                  英文用户访问时显示；为空则回退到中文。
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="shutdownAt">关闭时间</Label>
                <Input
                  id="shutdownAt"
                  type="datetime-local"
                  value={shutdownAtLocal}
                  onChange={(e) => setShutdownAtLocal(e.target.value)}
                  disabled={siteLoading}
                />
                <p className="text-xs text-muted-foreground">
                  使用浏览器本地时区；页面会基于访问者浏览器显示倒计时。
                </p>
              </div>
            </div>

            <div className="space-y-4 rounded-lg border p-4">
              <div>
                <Label className="text-base">整站背景音乐（BGM）</Label>
                <p className="mt-1 text-xs text-muted-foreground">
                  支持上传 mp3 / ogg / wav 等音频文件，上传后将在前台页面右下角出现播放控件；用户可随时暂停或调节音量。
                </p>
              </div>

              <div className="space-y-2">
                <Label>音频文件</Label>
                {bgmUrl ? (
                  <div className="flex flex-col gap-2">
                    <div className="flex items-center gap-2 rounded-md border bg-muted/40 px-3 py-2 text-sm">
                      <span className="flex-1 truncate font-mono text-xs text-muted-foreground">
                        {bgmUrl}
                      </span>
                      <button
                        type="button"
                        onClick={() => setBgmUrl("")}
                        className="text-destructive hover:text-destructive/80"
                        title="移除"
                      >
                        <Trash2 className="h-4 w-4" />
                      </button>
                    </div>
                    <audio
                      src={bgmUrl}
                      controls
                      className="w-full"
                      preload="metadata"
                    />
                    <div>
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => bgmFileRef.current?.click()}
                        disabled={bgmUploading}
                      >
                        {bgmUploading ? "上传中..." : "替换音频"}
                      </Button>
                    </div>
                  </div>
                ) : (
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() => bgmFileRef.current?.click()}
                    disabled={bgmUploading}
                    className="gap-2"
                  >
                    <Upload className="h-4 w-4" />
                    {bgmUploading ? "上传中..." : "上传音频"}
                  </Button>
                )}
                <input
                  ref={bgmFileRef}
                  type="file"
                  accept="audio/*"
                  className="hidden"
                  onChange={handleBgmUpload}
                />
              </div>

              <div className="flex items-start justify-between gap-4">
                <div className="space-y-1">
                  <Label>自动播放</Label>
                  <p className="text-xs text-muted-foreground">
                    浏览器可能会拦截自动播放，遇此情况会在用户首次点击页面后自动启动。用户主动暂停后将不再自动续播。
                  </p>
                </div>
                <Switch
                  checked={bgmAutoplay}
                  onCheckedChange={setBgmAutoplay}
                  disabled={siteLoading || !bgmUrl}
                />
              </div>

              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label htmlFor="bgmVolume">默认音量</Label>
                  <span className="font-mono text-xs text-muted-foreground tabular-nums">
                    {bgmVolume}
                  </span>
                </div>
                <input
                  id="bgmVolume"
                  type="range"
                  min={0}
                  max={100}
                  value={bgmVolume}
                  onChange={(e) => setBgmVolume(Number(e.target.value))}
                  disabled={siteLoading || !bgmUrl}
                  className="w-full"
                />
              </div>
            </div>

            <Button type="submit" disabled={siteLoading || siteSaving}>
              {siteSaving ? "保存中..." : "保存"}
            </Button>
          </form>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>启动器直链</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="space-y-3">
            <p className="text-sm text-muted-foreground">
              将该链接放到任意网页或外部站点，访问即可直接下载当前最新版本的
              Nanami 启动器。链接始终指向最新版本，无需手动更新。
            </p>
            <div className="flex items-center gap-2 rounded-md border bg-muted/40 px-3 py-2">
              <span className="flex-1 truncate font-mono text-xs">
                {launcherUrl || "/download/launcher"}
              </span>
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={handleCopyLauncherUrl}
                disabled={!launcherUrl}
                className="gap-1"
              >
                <Copy className="h-3.5 w-3.5" />
                复制
              </Button>
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={() =>
                  launcherUrl && window.open(launcherUrl, "_blank")
                }
                disabled={!launcherUrl}
                className="gap-1"
              >
                <ExternalLink className="h-3.5 w-3.5" />
                测试
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>修改密码</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handlePasswordSubmit} className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="currentPassword">当前密码</Label>
              <Input
                id="currentPassword"
                name="currentPassword"
                type="password"
                required
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="newPassword">新密码</Label>
              <Input
                id="newPassword"
                name="newPassword"
                type="password"
                required
                minLength={6}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="confirmPassword">确认新密码</Label>
              <Input
                id="confirmPassword"
                name="confirmPassword"
                type="password"
                required
                minLength={6}
              />
            </div>
            <Button type="submit" disabled={loading}>
              {loading ? "修改中..." : "修改密码"}
            </Button>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}
