"use client";

import * as React from "react";
import { Palette, Save } from "lucide-react";
import { toast } from "sonner";

import { ListPageCard } from "@/app/dashboard/_components";
import { SettingsPanelAppearance } from "@/app/customer/[tenant]/settings/_components/settings-panel-appearance";
import { Button } from "@/components/ui/button";
import { toastApiError } from "@/lib/toast-api-error";
import { dashboardCsrfHeader } from "@/lib/csrf.client";
import {
  applyUiPrefsLocally,
  previewUiPrefsLocally,
} from "@/lib/preferences/apply-ui-prefs-locally";
import { PREFERENCE_DEFAULTS, type PreferenceValueMap } from "@/lib/preferences/preferences-config";
import { syncPreferenceCookies } from "@/lib/preferences/sync-preference-cookies";
import { parseUiPrefs } from "@/lib/preferences/ui-prefs";
import { usePreferencesStore } from "@/stores/preferences/preferences-provider";

async function parseResponse(response: Response): Promise<PreferenceValueMap> {
  const data = (await response.json().catch(() => null)) as
    | { status?: string; message?: string; uiPrefs?: unknown }
    | null;

  if (!response.ok || !data || data.status === "error") {
    throw new Error(
      typeof data?.message === "string" && data.message.trim()
        ? data.message
        : "Appearance preferences could not be loaded.",
    );
  }

  return parseUiPrefs(data.uiPrefs ?? PREFERENCE_DEFAULTS);
}

export function DashboardAppearanceSettingsPage() {
  const [draft, setDraft] = React.useState<PreferenceValueMap>({ ...PREFERENCE_DEFAULTS });
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [isSaving, setIsSaving] = React.useState(false);
  const [isRestoring, setIsRestoring] = React.useState(false);

  const setThemeMode = usePreferencesStore((s) => s.setThemeMode);
  const setThemePreset = usePreferencesStore((s) => s.setThemePreset);
  const setFont = usePreferencesStore((s) => s.setFont);
  const setContentLayout = usePreferencesStore((s) => s.setContentLayout);
  const setNavbarStyle = usePreferencesStore((s) => s.setNavbarStyle);
  const setSidebarVariant = usePreferencesStore((s) => s.setSidebarVariant);
  const setSidebarCollapsible = usePreferencesStore((s) => s.setSidebarCollapsible);

  const applyToApp = React.useCallback(
    (prefs: PreferenceValueMap) => {
      applyUiPrefsLocally(prefs);
      setThemeMode(prefs.theme_mode);
      setThemePreset(prefs.theme_preset);
      setFont(prefs.font);
      setContentLayout(prefs.content_layout);
      setNavbarStyle(prefs.navbar_style);
      setSidebarVariant(prefs.sidebar_variant);
      setSidebarCollapsible(prefs.sidebar_collapsible);
      void syncPreferenceCookies(prefs);
    },
    [
      setThemeMode,
      setThemePreset,
      setFont,
      setContentLayout,
      setNavbarStyle,
      setSidebarVariant,
      setSidebarCollapsible,
    ],
  );

  React.useEffect(() => {
    let cancelled = false;
    async function load() {
      setLoading(true);
      setError(null);
      try {
        const response = await fetch("/dashboard/settings/appearance/ui-prefs", {
          method: "GET",
          credentials: "same-origin",
          headers: { Accept: "application/json" },
          cache: "no-store",
        });
        const prefs = await parseResponse(response);
        if (cancelled) return;
        setDraft(prefs);
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : "Appearance settings could not be loaded.");
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    void load();
    return () => {
      cancelled = true;
    };
  }, []);

  const handleSave = async () => {
    setIsSaving(true);
    try {
      const response = await fetch("/dashboard/settings/appearance/ui-prefs", {
        method: "POST",
        credentials: "same-origin",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        cache: "no-store",
        body: JSON.stringify({ uiPrefs: draft }),
      });
      const prefs = await parseResponse(response);
      setDraft(prefs);
      applyToApp(prefs);
      toast.success("Appearance settings saved");
    } catch (err) {
      toastApiError(err, "Unable to save appearance settings.");
    } finally {
      setIsSaving(false);
    }
  };

  const handleRestore = async () => {
    setIsRestoring(true);
    try {
      const response = await fetch("/dashboard/settings/appearance/ui-prefs", {
        method: "POST",
        credentials: "same-origin",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        cache: "no-store",
        body: JSON.stringify({ reset: true }),
      });
      const prefs = await parseResponse(response);
      setDraft(prefs);
      applyToApp(prefs);
      toast.success("Appearance defaults restored");
    } catch (err) {
      toastApiError(err, "Unable to restore appearance defaults.");
    } finally {
      setIsRestoring(false);
    }
  };

  return (
    <ListPageCard
      icon={Palette}
      title="Appearance"
      description="Theme, fonts, and layout preferences for your admin account."
      breadcrumb={[
        { label: "Settings", href: "/dashboard/settings/common" },
        { label: "Appearance" },
      ]}
    >
      <div className="space-y-6">
        <SettingsPanelAppearance
          draft={draft}
          isLoading={loading}
          errorMessage={error}
          onChange={(patch) => {
            setDraft((prev) => {
              const next = { ...prev, ...patch };
              previewUiPrefsLocally(next);
              return next;
            });
          }}
        />

        <div className="flex flex-wrap items-center gap-3 border-t pt-4">
          <Button
            type="button"
            variant="outline"
            disabled={isRestoring || loading || isSaving}
            onClick={() => void handleRestore()}
          >
            {isRestoring ? "Restoring…" : "Restore Defaults"}
          </Button>
          <Button
            className="gap-2"
            disabled={isSaving || isRestoring || loading}
            onClick={() => void handleSave()}
          >
            <Save className="size-4" />
            {isSaving ? "Saving…" : "Save changes"}
          </Button>
        </div>
      </div>
    </ListPageCard>
  );
}
