import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useQueryClient } from "@tanstack/react-query";
import {
  useUpdateClockStyle,
  useUpdateClockHour12,
  getGetMeQueryKey,
  type AuthUser,
  type ClockStyle as ClockStyleType,
} from "@workspace/api-client-react";
import { Clock as ClockIcon, Check, Eye, EyeOff } from "lucide-react";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Clock,
  CLOCK_STYLES,
  resolveClockStyle,
  resolveClockHour12,
  useNow,
  useHomeClockVisibility,
  useTopbarClockVisibility,
} from "@/components/clock";

type Props = {
  currentStyle: ClockStyleType | null | undefined;
  currentHour12: boolean | null | undefined;
};

export function ClockStylePicker({ currentStyle, currentHour12 }: Props) {
  const { t, i18n: i18nInstance } = useTranslation();
  const lang = i18nInstance.language;
  const queryClient = useQueryClient();
  const now = useNow();
  const [open, setOpen] = useState(false);

  const updateClockStyle = useUpdateClockStyle();
  const updateClockHour12 = useUpdateClockHour12();
  const active = resolveClockStyle(currentStyle);
  const activeHour12 = resolveClockHour12(currentHour12);
  const [homeClockVisible, setHomeClockVisible] = useHomeClockVisibility();
  const [topbarClockVisible, setTopbarClockVisible] = useTopbarClockVisibility();

  const choose = (style: ClockStyleType) => {
    const previous = queryClient.getQueryData<AuthUser>(getGetMeQueryKey());
    if (previous) {
      queryClient.setQueryData<AuthUser>(getGetMeQueryKey(), {
        ...previous,
        clockStyle: style,
      });
    }
    updateClockStyle.mutate(
      { data: { clockStyle: style } },
      {
        onSuccess: (data) => {
          queryClient.setQueryData(getGetMeQueryKey(), data);
        },
        onError: () => {
          if (previous) {
            queryClient.setQueryData(getGetMeQueryKey(), previous);
          } else {
            queryClient.invalidateQueries({ queryKey: getGetMeQueryKey() });
          }
        },
      },
    );
    setOpen(false);
  };

  const chooseHour12 = (next: boolean) => {
    if (next === activeHour12) return;
    const previous = queryClient.getQueryData<AuthUser>(getGetMeQueryKey());
    if (previous) {
      queryClient.setQueryData<AuthUser>(getGetMeQueryKey(), {
        ...previous,
        clockHour12: next,
      });
    }
    updateClockHour12.mutate(
      { data: { clockHour12: next } },
      {
        onSuccess: (data) => {
          queryClient.setQueryData(getGetMeQueryKey(), data);
        },
        onError: () => {
          if (previous) {
            queryClient.setQueryData(getGetMeQueryKey(), previous);
          } else {
            queryClient.invalidateQueries({ queryKey: getGetMeQueryKey() });
          }
        },
      },
    );
  };

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <button
          type="button"
          aria-label={t("home.clockStyle.label")}
          className="text-muted-foreground hover:text-foreground transition-colors p-1.5 rounded-lg hover:bg-foreground/5"
        >
          <ClockIcon size={18} />
        </button>
      </PopoverTrigger>
      <PopoverContent className="w-72 p-2" align="end">
        <button
          type="button"
          onClick={() => setHomeClockVisible(!homeClockVisible)}
          className="w-full flex items-center justify-between gap-3 px-2 py-2 rounded-lg text-start hover:bg-foreground/5 transition-colors mb-1"
        >
          <div className="flex items-center gap-2 min-w-0">
            {homeClockVisible ? (
              <Eye size={16} className="text-primary shrink-0" />
            ) : (
              <EyeOff size={16} className="text-muted-foreground shrink-0" />
            )}
            <span className="text-xs text-foreground font-medium truncate">
              {t("home.clockStyle.showWidget")}
            </span>
          </div>
          <span
            className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors ${
              homeClockVisible ? "bg-primary" : "bg-foreground/15"
            }`}
            aria-hidden="true"
          >
            <span
              className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${
                homeClockVisible
                  ? "translate-x-[18px] rtl:-translate-x-[18px]"
                  : "translate-x-0.5 rtl:-translate-x-0.5"
              }`}
            />
          </span>
        </button>
        <button
          type="button"
          onClick={() => setTopbarClockVisible(!topbarClockVisible)}
          className="w-full flex items-center justify-between gap-3 px-2 py-2 rounded-lg text-start hover:bg-foreground/5 transition-colors mb-1"
        >
          <div className="flex items-center gap-2 min-w-0">
            {topbarClockVisible ? (
              <Eye size={16} className="text-primary shrink-0" />
            ) : (
              <EyeOff size={16} className="text-muted-foreground shrink-0" />
            )}
            <span className="text-xs text-foreground font-medium truncate">
              {t("home.clockStyle.showTopbar")}
            </span>
          </div>
          <span
            className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors ${
              topbarClockVisible ? "bg-primary" : "bg-foreground/15"
            }`}
            aria-hidden="true"
          >
            <span
              className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${
                topbarClockVisible
                  ? "translate-x-[18px] rtl:-translate-x-[18px]"
                  : "translate-x-0.5 rtl:-translate-x-0.5"
              }`}
            />
          </span>
        </button>
        <div className="h-px bg-foreground/10 mx-1 mb-1" />
        <div className="px-2 py-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
          {t("home.clockStyle.hourFormat.label")}
        </div>
        <div
          className="grid grid-cols-2 gap-1 mx-1 mb-1 p-1 rounded-lg bg-foreground/5"
          role="group"
          aria-label={t("home.clockStyle.hourFormat.label")}
        >
          {([false, true] as const).map((value) => {
            const isActive = value === activeHour12;
            const labelKey = value ? "h12" : "h24";
            return (
              <button
                key={labelKey}
                type="button"
                onClick={() => chooseHour12(value)}
                disabled={updateClockHour12.isPending}
                aria-pressed={isActive}
                className={`text-xs font-medium px-2 py-1.5 rounded-md transition-colors ${
                  isActive
                    ? "bg-background text-foreground shadow-sm"
                    : "text-muted-foreground hover:text-foreground"
                }`}
              >
                {t(`home.clockStyle.hourFormat.${labelKey}`)}
              </button>
            );
          })}
        </div>
        <div className="h-px bg-foreground/10 mx-1 mb-1" />
        <div className="px-2 py-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
          {t("home.clockStyle.label")}
        </div>
        <div className="flex flex-col gap-1 max-h-[60vh] overflow-y-auto">
          {CLOCK_STYLES.map((style) => {
            const isActive = style === active;
            return (
              <button
                key={style}
                type="button"
                onClick={() => choose(style)}
                disabled={updateClockStyle.isPending}
                className={`flex items-center justify-between gap-3 px-2 py-2 rounded-lg text-start hover:bg-foreground/5 transition-colors ${
                  isActive ? "bg-primary/10" : ""
                }`}
              >
                <div className="flex items-center gap-3 min-w-0 flex-1">
                  <div className="shrink-0">
                    <Clock
                      style={style}
                      time={now}
                      lang={lang}
                      hour12={activeHour12}
                      size="sm"
                    />
                  </div>
                  <div className="text-xs text-foreground font-medium truncate">
                    {t(`home.clockStyle.options.${style}`)}
                  </div>
                </div>
                {isActive && <Check size={14} className="text-primary shrink-0" />}
              </button>
            );
          })}
        </div>
      </PopoverContent>
    </Popover>
  );
}
