"use client";

import { useEffect, useMemo, useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslations } from "next-intl";
import {
  applyCafeTheme,
  CAFE_MENU_STYLES,
  CAFE_MENU_TEXTURES,
  CAFE_PANEL_STYLES,
  CAFE_THEME_DENSITIES,
  CAFE_THEME_PALETTES,
  CAFE_THEME_RADIUS,
  DEFAULT_CAFE_THEME,
  normalizeCafeTheme,
  resolveThemeColors,
  COLOR_OPACITY_KEYS,
  type CafeTheme,
  type CafeThemeColorKey,
  type CafeThemeCustomColors,
} from "@/lib/cafe-theme";
import { apiPatch } from "@/lib/api/client";
import { cafeSettingsQueryKey, useCafeSettings, type CafeSettings } from "@/lib/hooks/use-cafe-settings";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { LabeledField } from "@/components/ui/labeled-field";
import { notify } from "@/lib/notify";
import { cn } from "@/lib/utils";
import { GuestMenuTemplatePreview } from "@/components/settings/guest-menu-template-preview";

type SettingsAppearancePanelProps = {
  cafeId: string;
};

const CUSTOM_COLOR_KEYS: CafeThemeColorKey[] = [
  "primary",
  "secondary",
  "accent",
  "background",
  "surface",
  "text",
  "textMuted",
  "destructive",
  "success",
];

export function SettingsAppearancePanel({ cafeId }: SettingsAppearancePanelProps) {
  const t = useTranslations("settings.appearance");
  const tCommon = useTranslations("common");
  const queryClient = useQueryClient();
  const { data: cafeSettings } = useCafeSettings(cafeId);

  const [theme, setTheme] = useState<CafeTheme>(DEFAULT_CAFE_THEME);

  useEffect(() => {
    if (!cafeSettings?.theme) return;
    setTheme(normalizeCafeTheme(cafeSettings.theme));
  }, [cafeSettings?.theme]);

  const previewColors = useMemo(() => resolveThemeColors(theme), [theme]);

  useEffect(() => {
    applyCafeTheme(theme);
  }, [theme]);

  const setCustom = (key: CafeThemeColorKey, value: string) => {
    setTheme((prev) => ({
      ...prev,
      custom: { ...(prev.custom ?? {}), [key]: value || null },
    }));
  };

  const setCustomOpacity = (key: CafeThemeColorKey, value: number) => {
    const opacityKey = COLOR_OPACITY_KEYS[key];
    setTheme((prev) => ({
      ...prev,
      custom: { ...(prev.custom ?? {}), [opacityKey]: value },
    }));
  };

  const clearCustom = () => {
    setTheme((prev) => ({ ...prev, custom: null }));
  };

  const save = useMutation({
    mutationFn: () =>
      apiPatch<CafeSettings>(`/api/cafes/${cafeId}/settings`, { theme }),
    onSuccess: (data) => {
      queryClient.setQueryData(cafeSettingsQueryKey(cafeId), data);
      notify.success(t("saved"));
    },
  });

  return (
    <div className="space-y-4">
      <Card className="rounded-xl border border-border/80 shadow-sm">
        <CardHeader className="pb-2">
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {t("paletteSection")}
          </p>
          <CardTitle className="text-base">{t("paletteTitle")}</CardTitle>
          <p className="text-xs text-muted-foreground">{t("paletteHint")}</p>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4">
            {CAFE_THEME_PALETTES.map((palette) => {
              const selected = theme.paletteId === palette.id;
              return (
                <button
                  key={palette.id}
                  type="button"
                  onClick={() => setTheme((p) => ({ ...p, paletteId: palette.id }))}
                  className={cn(
                    "flex items-center gap-2 rounded-lg border p-2 text-start transition-all active:scale-[0.98]",
                    selected
                      ? "border-primary bg-accent ring-1 ring-primary/30"
                      : "border-border/80 hover:border-primary/40"
                  )}
                >
                  <span
                    className="h-8 w-8 shrink-0 rounded-md border border-black/10 shadow-inner"
                    style={{
                      background: `linear-gradient(135deg, ${palette.primary} 50%, ${palette.secondary} 50%)`,
                    }}
                  />
                  <span className="min-w-0 truncate text-xs font-medium">
                    {t(`palettes.${palette.id}`)}
                  </span>
                </button>
              );
            })}
          </div>
        </CardContent>
      </Card>

      <Card className="overflow-hidden rounded-xl border border-border/80 shadow-sm">
        <CardHeader className="pb-2">
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {t("dashboardSection")}
          </p>
          <CardTitle className="text-base">{t("dashboardTitle")}</CardTitle>
          <p className="text-xs text-muted-foreground">{t("dashboardDesc")}</p>
        </CardHeader>
        <CardContent className="space-y-4">
          <StyleChipRow
            label={t("panelStyle")}
            options={CAFE_PANEL_STYLES}
            value={theme.panelStyle}
            labelPrefix="panelStyles"
            onChange={(panelStyle) => setTheme((p) => ({ ...p, panelStyle }))}
          />
          <StyleChipRow
            label={t("density")}
            options={CAFE_THEME_DENSITIES}
            value={theme.density}
            labelPrefix="densities"
            onChange={(density) => setTheme((p) => ({ ...p, density }))}
          />
          <StyleChipRow
            label={t("radius")}
            options={CAFE_THEME_RADIUS}
            value={theme.radius}
            labelPrefix="radiusOptions"
            onChange={(radius) => setTheme((p) => ({ ...p, radius }))}
          />

          <div className="border-t border-border/60 pt-4">
            <p className="mb-1 text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
              {t("dashboardPreviewSection")}
            </p>
            <p className="mb-3 text-sm font-medium text-foreground">{t("dashboardPreviewTitle")}</p>
            <div
              className="rounded-xl border p-4 transition-colors"
              style={{ background: previewColors.background }}
              data-panel-style={theme.panelStyle}
            >
              <div className="flex gap-3">
                <div
                  className="theme-preview-sidebar w-24 shrink-0 rounded-lg p-2 shadow-sm"
                  style={{ background: previewColors.surface }}
                >
                  <div
                    className="mb-2 h-6 rounded-md px-2 text-[10px] font-medium leading-6 text-white"
                    style={{ background: previewColors.primary }}
                  >
                    {t("previewNav")}
                  </div>
                  <div
                    className="h-5 rounded-md opacity-80"
                    style={{ background: previewColors.secondary }}
                  />
                  <div
                    className="mt-1.5 h-5 rounded-md opacity-60"
                    style={{ background: previewColors.secondary }}
                  />
                </div>
                <div className="min-w-0 flex-1 space-y-2">
                  <div
                    className="theme-preview-menu-card rounded-lg border p-3 shadow-sm"
                    style={{
                      background: previewColors.surface,
                      borderColor: `${previewColors.primary}33`,
                    }}
                  >
                    <p className="text-sm font-medium" style={{ color: previewColors.text }}>
                      {t("previewItem")}
                    </p>
                    <p className="text-xs" style={{ color: previewColors.textMuted }}>
                      ۱۲۰٬۰۰۰ ت
                    </p>
                    <span
                      className="mt-2 inline-block rounded-md px-2 py-0.5 text-[10px] text-white"
                      style={{ background: previewColors.primary }}
                    >
                      {t("previewCta")}
                    </span>
                  </div>
                </div>
              </div>
            </div>
            <p className="mt-2 text-[11px] text-muted-foreground">{t("dashboardPreviewHint")}</p>
          </div>
        </CardContent>
      </Card>

      <Card className="rounded-xl border border-border/80 shadow-sm">
        <CardHeader className="pb-2">
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {t("guestMenuSection")}
          </p>
          <CardTitle className="text-base">{t("guestMenuTitle")}</CardTitle>
          <p className="text-xs text-muted-foreground">{t("guestMenuDesc")}</p>
        </CardHeader>
        <CardContent className="space-y-4">
          <StyleChipRow
            label={t("guestMenuStyle")}
            options={CAFE_MENU_STYLES}
            value={theme.menuStyle}
            labelPrefix="menuStyles"
            onChange={(menuStyle) => setTheme((p) => ({ ...p, menuStyle }))}
          />
          <div className="space-y-2">
            <p className="text-xs font-medium text-muted-foreground">{t("menuTexture")}</p>
            <TextureSwatchGrid
              textures={CAFE_MENU_TEXTURES}
              value={theme.menuTexture}
              backgroundColor={previewColors.background}
              onChange={(menuTexture) => setTheme((p) => ({ ...p, menuTexture }))}
              labelPrefix="menuTextures"
            />
          </div>

          <div className="border-t border-border/60 pt-4">
            <p className="mb-3 text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
              {t("guestMenuPreviewSection")}
            </p>
            <GuestMenuTemplatePreview
              theme={theme}
              cafeName={cafeSettings?.name ?? undefined}
            />
          </div>
        </CardContent>
      </Card>

      <Card className="rounded-xl border border-border/80 shadow-sm">
        <CardHeader className="pb-2">
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {t("customSection")}
          </p>
          <CardTitle className="text-base">{t("customTitle")}</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <p className="text-xs text-muted-foreground">{t("customHint")}</p>
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
            {CUSTOM_COLOR_KEYS.map((key) => {
              const base = resolveThemeColors({ ...theme, custom: null });
              const value = theme.custom?.[key] ?? paletteColorForKey(base, key);
              const opacityKey = COLOR_OPACITY_KEYS[key];
              const opacity =
                (theme.custom?.[opacityKey] as number | null | undefined) ?? 100;
              return (
                <LabeledField key={key} label={t(`colors.${key}`)}>
                  <div className="space-y-2">
                    <div className="flex items-center gap-2">
                      <input
                        type="color"
                        value={value.startsWith("#") ? value : "#0F6E56"}
                        onChange={(e) => setCustom(key, e.target.value)}
                        className="h-9 w-12 cursor-pointer rounded border border-border/80 bg-card"
                      />
                      <input
                        type="text"
                        value={theme.custom?.[key] ?? ""}
                        placeholder={value}
                        onChange={(e) => setCustom(key, e.target.value)}
                        className="flex-1 rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs"
                        dir="ltr"
                      />
                    </div>
                    <div className="flex items-center gap-2">
                      <span className="text-[11px] text-muted-foreground">{t("colorOpacity")}</span>
                      <input
                        type="range"
                        min={0}
                        max={100}
                        value={opacity}
                        onChange={(e) => setCustomOpacity(key, Number(e.target.value))}
                        className="flex-1"
                      />
                      <span className="w-8 text-end font-mono text-[11px] text-muted-foreground" dir="ltr">
                        {opacity}%
                      </span>
                    </div>
                  </div>
                </LabeledField>
              );
            })}
          </div>
          <Button type="button" size="sm" variant="ghost" onClick={clearCustom}>
            {t("resetCustom")}
          </Button>
        </CardContent>
      </Card>

      <Button
        className="bg-primary text-primary-foreground hover:opacity-90"
        disabled={save.isPending}
        onClick={() => save.mutate()}
      >
        {tCommon("save")}
      </Button>
    </div>
  );
}

function paletteColorForKey(
  palette: ReturnType<typeof resolveThemeColors>,
  key: CafeThemeColorKey
): string {
  switch (key) {
    case "primary":
      return palette.primary;
    case "secondary":
      return palette.secondary;
    case "accent":
      return palette.accent;
    case "background":
      return palette.background;
    case "surface":
      return palette.surface;
    case "text":
      return palette.text;
    case "textMuted":
      return palette.textMuted;
    case "destructive":
      return palette.destructive;
    case "success":
      return palette.success;
    default:
      return palette.primary;
  }
}

function TextureSwatchGrid<T extends string>({
  textures,
  value,
  backgroundColor,
  onChange,
  labelPrefix,
}: {
  textures: readonly T[];
  value: T;
  backgroundColor: string;
  onChange: (v: T) => void;
  labelPrefix: string;
}) {
  const t = useTranslations("settings.appearance");
  return (
    <div className="grid grid-cols-4 gap-2 sm:grid-cols-8">
      {textures.map((tex) => {
        const selected = value === tex;
        return (
          <button
            key={tex}
            type="button"
            title={t(`${labelPrefix}.${tex}` as any)}
            onClick={() => onChange(tex)}
            className={cn(
              "qr-texture-swatch transition-all active:scale-[0.98]",
              selected ? "ring-2 ring-primary ring-offset-1" : "opacity-90 hover:opacity-100"
            )}
            data-qr-texture={tex}
            style={{ ["--qr-bg" as string]: backgroundColor }}
          >
            <span className="sr-only">{t(`${labelPrefix}.${tex}` as any)}</span>
          </button>
        );
      })}
    </div>
  );
}

function StyleChipRow<T extends string>({
  label,
  options,
  value,
  labelPrefix,
  onChange,
}: {
  label: string;
  options: readonly T[];
  value: T;
  labelPrefix: string;
  onChange: (v: T) => void;
}) {
  const t = useTranslations("settings.appearance");
  return (
    <div className="space-y-2">
      <p className="text-xs font-medium text-muted-foreground">{label}</p>
      <div className="flex flex-wrap gap-1.5">
        {options.map((opt) => (
          <button
            key={opt}
            type="button"
            onClick={() => onChange(opt)}
            className={cn(
              "rounded-md border px-2.5 py-1 text-xs font-medium transition-colors",
              value === opt
                ? "border-primary bg-accent text-primary"
                : "border-border/80 text-muted-foreground hover:border-primary/40"
            )}
          >
            {t(`${labelPrefix}.${opt}` as any)}
          </button>
        ))}
      </div>
    </div>
  );
}
