"use client";

import { invoke } from "@tauri-apps/api/core";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { FiWifi } from "react-icons/fi";
import { LuLayers, LuPuzzle, LuShield, LuUsers } from "react-icons/lu";
import { LoadingButton } from "@/components/loading-button";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { MOTION_EASE_OUT } from "@/lib/motion";
import { showErrorToast, showSuccessToast } from "@/lib/toast-utils";

interface UnsyncedEntityCounts {
  proxies: number;
  groups: number;
  vpns: number;
  extensions: number;
  extension_groups: number;
}

interface SyncAllDialogProps {
  isOpen: boolean;
  onClose: () => void;
}

export function SyncAllDialog({ isOpen, onClose }: SyncAllDialogProps) {
  const { t } = useTranslation();
  const reduceMotion = useReducedMotion();
  const [counts, setCounts] = useState<UnsyncedEntityCounts | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [isEnabling, setIsEnabling] = useState(false);

  const loadCounts = useCallback(async () => {
    setIsLoading(true);
    try {
      const result = await invoke<UnsyncedEntityCounts>(
        "get_unsynced_entity_counts",
      );
      setCounts(result);
    } catch (error) {
      console.error("Failed to get unsynced entity counts:", error);
      setCounts(null);
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    if (isOpen) {
      void loadCounts();
    }
  }, [isOpen, loadCounts]);

  const handleEnableAll = useCallback(async () => {
    setIsEnabling(true);
    try {
      await invoke("enable_sync_for_all_entities");
      showSuccessToast(t("syncAll.success"));
      onClose();
    } catch (error) {
      console.error("Failed to enable sync for all entities:", error);
      showErrorToast(String(error));
    } finally {
      setIsEnabling(false);
    }
  }, [onClose, t]);

  const items = useMemo(() => {
    if (!counts) return [];
    return [
      {
        key: "proxies",
        count: counts.proxies,
        label: t("syncAll.labels.proxies"),
        Icon: FiWifi,
      },
      {
        key: "vpns",
        count: counts.vpns,
        label: t("syncAll.labels.vpns"),
        Icon: LuShield,
      },
      {
        key: "groups",
        count: counts.groups,
        label: t("syncAll.labels.groups"),
        Icon: LuUsers,
      },
      {
        key: "extensions",
        count: counts.extensions,
        label: t("syncAll.labels.extensions"),
        Icon: LuPuzzle,
      },
      {
        key: "extensionGroups",
        count: counts.extension_groups,
        label: t("syncAll.labels.extensionGroups"),
        Icon: LuLayers,
      },
    ].filter((item) => item.count > 0);
  }, [counts, t]);

  const totalCount = items.reduce((sum, item) => sum + item.count, 0);

  // Don't render anything when there's nothing to sync — the parent
  // mounts this dialog eagerly after login, so silent-close is correct.
  if (!isLoading && totalCount === 0) {
    return null;
  }

  return (
    <Dialog
      open={isOpen && (isLoading || totalCount > 0)}
      onOpenChange={onClose}
    >
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>{t("syncAll.title")}</DialogTitle>
          <DialogDescription>{t("syncAll.description")}</DialogDescription>
        </DialogHeader>

        <AnimatePresence initial={false} mode="wait">
          {isLoading ? (
            <motion.div
              key="loading"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{
                duration: reduceMotion ? 0.15 : 0.12,
                ease: MOTION_EASE_OUT,
              }}
              className="flex justify-center py-8"
            >
              <div className="size-6 animate-spin rounded-full border-2 border-current border-t-transparent" />
            </motion.div>
          ) : (
            <motion.div
              key="results"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              transition={{
                duration: reduceMotion ? 0.15 : 0.16,
                ease: MOTION_EASE_OUT,
              }}
              className="grid grid-cols-2 gap-2 py-2"
            >
              {items.map(({ key, count, label, Icon }, index) => (
                <motion.div
                  key={key}
                  initial={{ opacity: 0, y: reduceMotion ? 0 : 4 }}
                  animate={{ opacity: 1, y: 0 }}
                  transition={{
                    duration: reduceMotion ? 0.15 : 0.16,
                    delay: reduceMotion ? 0 : Math.min(index * 0.03, 0.12),
                    ease: MOTION_EASE_OUT,
                  }}
                  className="flex items-center gap-3 rounded-lg border border-border/60 bg-card/50 p-3 transition-colors hover:bg-card"
                >
                  <div className="flex size-9 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary">
                    <Icon className="size-4" />
                  </div>
                  <div className="min-w-0 flex-1 truncate text-sm font-medium">
                    {label}
                  </div>
                  <Badge
                    variant="secondary"
                    className="shrink-0 px-2 tabular-nums"
                  >
                    {count}
                  </Badge>
                </motion.div>
              ))}
            </motion.div>
          )}
        </AnimatePresence>

        <DialogFooter className="flex gap-2">
          <Button variant="outline" onClick={onClose} disabled={isEnabling}>
            {t("syncAll.skip")}
          </Button>
          <LoadingButton
            onClick={handleEnableAll}
            isLoading={isEnabling}
            disabled={isLoading}
          >
            {t("syncAll.enableAll")}
          </LoadingButton>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
