"use client";

import { Check, Monitor, Moon, Sun } from "lucide-react";

import { updateUiPrefsClient } from "@/app/customer/[tenant]/settings/_lib/ui-prefs-api";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { dashboardCsrfHeader } from "@/lib/csrf.client";
import { persistPreference } from "@/lib/preferences/preferences-storage";
import type { PreferenceValueMap } from "@/lib/preferences/preferences-config";
import type { ThemeMode } from "@/lib/preferences/theme";
import { parseUiPrefs } from "@/lib/preferences/ui-prefs";
import { cn } from "@/lib/utils";
import { usePreferencesStore } from "@/stores/preferences/preferences-provider";

const THEME_CYCLE = ["light", "dark", "system"] as const;

const THEME_OPTIONS: { value: ThemeMode; label: string; icon: typeof Sun }[] = [
  { value: "light", label: "Light", icon: Sun },
  { value: "dark", label: "Dark", icon: Moon },
  { value: "system", label: "System", icon: Monitor },
];

async function saveBackendThemePrefs(prefs: PreferenceValueMap) {
  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: prefs }),
  });
  const data = (await response.json().catch(() => null)) as
    | { status?: string; uiPrefs?: unknown }
    | null;
  if (!response.ok || !data || data.status === "error") {
    throw new Error("Could not save appearance preferences.");
  }
  return parseUiPrefs(data.uiPrefs ?? prefs);
}

export function ThemeSwitcher({
  tenant,
  audience = "customer",
}: {
  tenant?: string | null;
  audience?: "customer" | "backend";
} = {}) {
  const themeMode = usePreferencesStore((s) => s.themeMode);
  const setThemeMode = usePreferencesStore((s) => s.setThemeMode);
  const themePreset = usePreferencesStore((s) => s.themePreset);
  const font = usePreferencesStore((s) => s.font);
  const contentLayout = usePreferencesStore((s) => s.contentLayout);
  const navbarStyle = usePreferencesStore((s) => s.navbarStyle);
  const sidebarVariant = usePreferencesStore((s) => s.sidebarVariant);
  const sidebarCollapsible = usePreferencesStore((s) => s.sidebarCollapsible);

  const applyTheme = (nextTheme: ThemeMode) => {
    setThemeMode(nextTheme);
    void persistPreference("theme_mode", nextTheme);

    const prefs: PreferenceValueMap = {
      theme_mode: nextTheme,
      theme_preset: themePreset,
      font,
      content_layout: contentLayout,
      navbar_style: navbarStyle,
      sidebar_variant: sidebarVariant,
      sidebar_collapsible: sidebarCollapsible,
    };

    if (audience === "backend") {
      void saveBackendThemePrefs(prefs).catch(() => {
        // Cookie apply already succeeded.
      });
      return;
    }

    if (tenant?.trim()) {
      void updateUiPrefsClient(prefs).catch(() => {
        // Cookie/local apply already succeeded; DB sync can retry on next save/login.
      });
    }
  };

  const cycleTheme = () => {
    const currentIndex = THEME_CYCLE.indexOf(themeMode);
    const nextTheme = THEME_CYCLE[(currentIndex + 1) % THEME_CYCLE.length];
    applyTheme(nextTheme);
  };

  if (audience === "backend") {
    return (
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            size="icon"
            variant="outline"
            aria-label={`Theme: ${themeMode}. Open light/dark mode selector`}
          >
            <Sun className="hidden [html[data-theme-mode=light]_&]:block dark:hidden" />
            <Moon className="hidden dark:block [html[data-theme-mode=system]_&]:hidden" />
            <Monitor className="hidden [html[data-theme-mode=system]_&]:block" />
            <span className="sr-only">Select theme</span>
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" className="min-w-40">
          {THEME_OPTIONS.map((option) => {
            const Icon = option.icon;
            const selected = themeMode === option.value;
            return (
              <DropdownMenuItem
                key={option.value}
                onClick={() => applyTheme(option.value)}
                className="gap-2"
              >
                <Icon className="size-4" />
                <span className="flex-1">{option.label}</span>
                <Check className={cn("size-4", selected ? "opacity-100" : "opacity-0")} />
              </DropdownMenuItem>
            );
          })}
        </DropdownMenuContent>
      </DropdownMenu>
    );
  }

  return (
    <Button
      size="icon"
      variant="outline"
      onClick={cycleTheme}
      aria-label={`Current theme: ${themeMode}. Click to cycle themes`}
    >
      <Monitor className="hidden [html[data-theme-mode=system]_&]:block" />
      <Sun className="hidden dark:block [html[data-theme-mode=system]_&]:hidden" />
      <Moon className="block dark:hidden [html[data-theme-mode=system]_&]:hidden" />
    </Button>
  );
}
