"use client";

import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import {
  getAdminSettings,
  updateAdminSetting,
} from "@/api/admin-settings";
import { WalletConfigDocScreen } from "@/modules/config/doc/wallet-config-doc-screen";
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 { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { LotteryApiBizError } from "@/types/api/errors";

const DRAW_GROUP = "draw";
const SETTLEMENT_GROUP = "settlement";

const DRAW_KEYS = {
  REQUIRE_MANUAL_REVIEW: "draw.require_manual_review",
  COOLDOWN_MINUTES: "draw.cooldown_minutes",
  AUTO_SETTLEMENT: "settlement.auto_run_on_tick",
} as const;

const FRONTEND_GROUP = "frontend";
const FRONTEND_KEYS = {
  PLAY_RULES_HTML: "frontend.play_rules_html",
  PLAY_RULES_HTML_ZH: "frontend.play_rules_html_zh",
  PLAY_RULES_HTML_EN: "frontend.play_rules_html_en",
  PLAY_RULES_HTML_NE: "frontend.play_rules_html_ne",
} as const;

interface RuntimeDraft {
  requireManualReview: boolean;
  cooldownMinutes: string;
  autoSettlement: boolean;
  playRulesHtmlZh: string;
  playRulesHtmlEn: string;
  playRulesHtmlNe: string;
}

function BinaryChoice({
  active,
  disabled,
  onChange,
  leftLabel,
  rightLabel,
}: {
  active: boolean;
  disabled: boolean;
  onChange: (value: boolean) => void;
  leftLabel: string;
  rightLabel: string;
}) {
  return (
    <div className="inline-flex rounded-full border border-border/60 bg-background p-1">
      <Button
        type="button"
        size="sm"
        variant={!active ? "default" : "ghost"}
        className={!active ? "h-8 rounded-full px-3" : "h-8 rounded-full px-3 text-muted-foreground"}
        disabled={disabled}
        onClick={() => onChange(false)}
      >
        {leftLabel}
      </Button>
      <Button
        type="button"
        size="sm"
        variant={active ? "default" : "ghost"}
        className={active ? "h-8 rounded-full px-3" : "h-8 rounded-full px-3 text-muted-foreground"}
        disabled={disabled}
        onClick={() => onChange(true)}
      >
        {rightLabel}
      </Button>
    </div>
  );
}

function SaveActions({
  dirty,
  loading,
  saving,
  onSave,
  onDiscard,
  saveLabel,
  savingLabel,
  discardLabel,
}: {
  dirty: boolean;
  loading: boolean;
  saving: boolean;
  onSave: () => void;
  onDiscard: () => void;
  saveLabel: string;
  savingLabel: string;
  discardLabel: string;
}) {
  return (
    <div className="flex flex-wrap items-center gap-3 pt-2">
      <Button type="button" onClick={onSave} disabled={!dirty || loading || saving}>
        {saving ? savingLabel : saveLabel}
      </Button>
      {dirty ? (
        <Button type="button" variant="outline" onClick={onDiscard}>
          {discardLabel}
        </Button>
      ) : null}
    </div>
  );
}

export function SystemSettingsScreen() {
  const { t } = useTranslation(["common", "config", "adminUsers"]);
  const [draft, setDraft] = useState<RuntimeDraft>({
    requireManualReview: false,
    cooldownMinutes: "15",
    autoSettlement: true,
    playRulesHtmlZh: "",
    playRulesHtmlEn: "",
    playRulesHtmlNe: "",
  });
  const [saved, setSaved] = useState<RuntimeDraft>({
    requireManualReview: false,
    cooldownMinutes: "15",
    autoSettlement: true,
    playRulesHtmlZh: "",
    playRulesHtmlEn: "",
    playRulesHtmlNe: "",
  });
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [dirty, setDirty] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [drawRes, settlementRes, frontendRes] = await Promise.all([
        getAdminSettings(DRAW_GROUP),
        getAdminSettings(SETTLEMENT_GROUP),
        getAdminSettings(FRONTEND_GROUP),
      ]);

      const kv: Record<string, unknown> = {};
      for (const item of [...drawRes.items, ...settlementRes.items, ...frontendRes.items]) {
        kv[item.key] = item.value;
      }

      const legacyHtml = String(kv[FRONTEND_KEYS.PLAY_RULES_HTML] ?? "");
      const nextDraft: RuntimeDraft = {
        requireManualReview: Boolean(kv[DRAW_KEYS.REQUIRE_MANUAL_REVIEW] ?? false),
        cooldownMinutes: String(kv[DRAW_KEYS.COOLDOWN_MINUTES] ?? 15),
        autoSettlement: Boolean(kv[DRAW_KEYS.AUTO_SETTLEMENT] ?? true),
        playRulesHtmlZh: String(kv[FRONTEND_KEYS.PLAY_RULES_HTML_ZH] ?? legacyHtml),
        playRulesHtmlEn: String(kv[FRONTEND_KEYS.PLAY_RULES_HTML_EN] ?? ""),
        playRulesHtmlNe: String(kv[FRONTEND_KEYS.PLAY_RULES_HTML_NE] ?? ""),
      };
      setDraft(nextDraft);
      setSaved(nextDraft);
      setDirty(false);
    } catch {
      toast.error(t("system.loadFailed", { ns: "config" }));
    } finally {
      setLoading(false);
    }
  }, [t]);

  useEffect(() => {
    queueMicrotask(() => {
      void load();
    });
  }, [load]);

  const updateDraft = <K extends keyof RuntimeDraft>(field: K, value: RuntimeDraft[K]) => {
    setDraft((prev) => ({ ...prev, [field]: value }));
    setDirty(true);
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      await updateAdminSetting(DRAW_KEYS.REQUIRE_MANUAL_REVIEW, draft.requireManualReview);
      await updateAdminSetting(
        DRAW_KEYS.COOLDOWN_MINUTES,
        Math.max(0, Number.parseInt(draft.cooldownMinutes || "0", 10) || 0),
      );
      await updateAdminSetting(DRAW_KEYS.AUTO_SETTLEMENT, draft.autoSettlement);
      await updateAdminSetting(FRONTEND_KEYS.PLAY_RULES_HTML_ZH, draft.playRulesHtmlZh);
      await updateAdminSetting(FRONTEND_KEYS.PLAY_RULES_HTML_EN, draft.playRulesHtmlEn);
      await updateAdminSetting(FRONTEND_KEYS.PLAY_RULES_HTML_NE, draft.playRulesHtmlNe);
      await updateAdminSetting(FRONTEND_KEYS.PLAY_RULES_HTML, draft.playRulesHtmlZh);
      toast.success(t("system.saveSuccess", { ns: "config" }));
      setSaved(draft);
      setDirty(false);
    } catch (error) {
      toast.error(
        error instanceof LotteryApiBizError ? error.message : t("system.saveFailed", { ns: "config" }),
      );
    } finally {
      setSaving(false);
    }
  };

  const saveLabel = t("actions.save", { ns: "adminUsers" });
  const savingLabel = t("saving", { ns: "adminUsers" });
  const discardLabel = t("system.discard", { ns: "config" });

  return (
    <div className="flex flex-col gap-10">
      <section className="space-y-4">
        <h2 className="border-b border-border/60 pb-3 text-base font-semibold text-foreground">
          {t("system.title", { ns: "config" })}
        </h2>

        <div className="space-y-5">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <Label className="text-sm font-medium">{t("system.fields.manualReview", { ns: "config" })}</Label>
            <BinaryChoice
              active={draft.requireManualReview}
              disabled={loading || saving}
              onChange={(value) => updateDraft("requireManualReview", value)}
              leftLabel={t("system.states.disabled", { ns: "config" })}
              rightLabel={t("system.states.enabled", { ns: "config" })}
            />
          </div>

          <div className="h-px bg-border/60" />

          <div className="flex flex-wrap items-center justify-between gap-3">
            <Label className="text-sm font-medium">{t("system.fields.autoSettlement", { ns: "config" })}</Label>
            <BinaryChoice
              active={draft.autoSettlement}
              disabled={loading || saving}
              onChange={(value) => updateDraft("autoSettlement", value)}
              leftLabel={t("system.states.disabled", { ns: "config" })}
              rightLabel={t("system.states.enabled", { ns: "config" })}
            />
          </div>

          <div className="h-px bg-border/60" />

          <div className="grid max-w-xs gap-2">
            <Label htmlFor="cooldown-minutes" className="text-sm font-medium">
              {t("system.fields.cooldownMinutes", { ns: "config" })}
            </Label>
            <Input
              id="cooldown-minutes"
              type="number"
              min="0"
              step="1"
              value={draft.cooldownMinutes}
              onChange={(e) => updateDraft("cooldownMinutes", e.target.value)}
              disabled={loading || saving}
            />
          </div>
        </div>

      </section>

      <section className="space-y-4">
        <h2 className="border-b border-border/60 pb-3 text-base font-semibold text-foreground">
          {t("wallet.title", { ns: "config" })}
        </h2>
        <WalletConfigDocScreen embedded />
      </section>

      <section className="space-y-4">
        <h2 className="border-b border-border/60 pb-3 text-base font-semibold text-foreground">
          {t("system.frontendConfig", { ns: "config" })}
        </h2>

        <div className="grid gap-2">
          <Label className="text-sm font-medium">
            {t("system.fields.playRulesHtml", { ns: "config" })}
          </Label>
          <p className="text-xs text-muted-foreground">
            {t("system.fields.playRulesHtmlDesc", { ns: "config" })}
          </p>
          <Tabs defaultValue="zh" className="w-full">
            <TabsList className="w-full max-w-md">
              <TabsTrigger value="zh">{t("play.locales.zh", { ns: "config" })}</TabsTrigger>
              <TabsTrigger value="en">{t("play.locales.en", { ns: "config" })}</TabsTrigger>
              <TabsTrigger value="ne">{t("play.locales.ne", { ns: "config" })}</TabsTrigger>
            </TabsList>
            <TabsContent value="zh" className="mt-3">
              <Textarea
                id="play-rules-html-zh"
                value={draft.playRulesHtmlZh}
                onChange={(e) => updateDraft("playRulesHtmlZh", e.target.value)}
                disabled={loading || saving}
                className="min-h-[200px] font-mono text-xs"
                placeholder="<div>...</div>"
              />
            </TabsContent>
            <TabsContent value="en" className="mt-3">
              <Textarea
                id="play-rules-html-en"
                value={draft.playRulesHtmlEn}
                onChange={(e) => updateDraft("playRulesHtmlEn", e.target.value)}
                disabled={loading || saving}
                className="min-h-[200px] font-mono text-xs"
                placeholder="<div>...</div>"
              />
            </TabsContent>
            <TabsContent value="ne" className="mt-3">
              <Textarea
                id="play-rules-html-ne"
                value={draft.playRulesHtmlNe}
                onChange={(e) => updateDraft("playRulesHtmlNe", e.target.value)}
                disabled={loading || saving}
                className="min-h-[200px] font-mono text-xs"
                placeholder="<div>...</div>"
              />
            </TabsContent>
          </Tabs>
        </div>

      </section>

      <SaveActions
        dirty={dirty}
        loading={loading}
        saving={saving}
        onSave={() => void handleSave()}
        onDiscard={() => {
          setDraft(saved);
          setDirty(false);
        }}
        saveLabel={saveLabel}
        savingLabel={savingLabel}
        discardLabel={discardLabel}
      />
    </div>
  );
}
