"use client";

import { invoke } from "@tauri-apps/api/core";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { FiCheck } from "react-icons/fi";
import { toast } from "sonner";
import { FlagIcon } from "@/components/flag-icon";
import { Button } from "@/components/ui/button";
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { formatRelativeTime } from "@/lib/flag-utils";
import { MOTION_EASE_OUT } from "@/lib/motion";
import type { ProxyCheckResult, StoredProxy } from "@/types";

interface ProxyCheckButtonProps {
  proxy: StoredProxy;
  profileId: string;
  checkingProfileId: string | null;
  cachedResult?: ProxyCheckResult;
  onCheckComplete?: (result: ProxyCheckResult) => void;
  onCheckFailed?: (result: ProxyCheckResult) => void;
  disabled?: boolean;
  setCheckingProfileId?: (id: string | null) => void;
}

export function ProxyCheckButton({
  proxy,
  profileId,
  checkingProfileId,
  cachedResult,
  onCheckComplete,
  onCheckFailed,
  disabled = false,
  setCheckingProfileId,
}: ProxyCheckButtonProps) {
  const { t } = useTranslation();
  const reduceMotion = useReducedMotion();
  const [localResult, setLocalResult] = React.useState<
    ProxyCheckResult | undefined
  >(cachedResult);

  React.useEffect(() => {
    setLocalResult(cachedResult);
  }, [cachedResult]);

  const handleCheck = React.useCallback(async () => {
    if (checkingProfileId === profileId) return;

    setCheckingProfileId?.(profileId);
    try {
      const result = await invoke<ProxyCheckResult>("check_proxy_validity", {
        proxyId: proxy.id,
        proxySettings: proxy.proxy_settings,
      });
      setLocalResult(result);
      onCheckComplete?.(result);

      // Show toast with location
      const locationParts: string[] = [];
      if (result.city) locationParts.push(result.city);
      if (result.country) locationParts.push(result.country);
      const location =
        locationParts.length > 0
          ? locationParts.join(", ")
          : t("proxyCheck.unknownLocation");

      toast.success(
        <div className="flex flex-col">
          {t("proxyCheck.locationToast")}
          <div className="flex items-center whitespace-nowrap">
            {location}
            {result.country_code && (
              <FlagIcon
                countryCode={result.country_code}
                className="ml-1 text-sm"
              />
            )}
          </div>
        </div>,
      );
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : String(error);
      toast.error(t("proxyCheck.failed", { error: errorMessage }));

      // Save failed check result
      const failedResult: ProxyCheckResult = {
        ip: "",
        city: undefined,
        country: undefined,
        country_code: undefined,
        timestamp: Math.floor(Date.now() / 1000),
        is_valid: false,
      };
      setLocalResult(failedResult);
      onCheckFailed?.(failedResult);
    } finally {
      setCheckingProfileId?.(null);
    }
  }, [
    proxy,
    profileId,
    checkingProfileId,
    onCheckComplete,
    onCheckFailed,
    setCheckingProfileId,
    t,
  ]);

  const isCurrentlyChecking = checkingProfileId === profileId;
  const result = localResult;
  const statusKey = isCurrentlyChecking
    ? "checking"
    : result?.is_valid && result.country_code
      ? "valid-location"
      : result && !result.is_valid
        ? "invalid"
        : "idle";

  return (
    <Tooltip>
      <TooltipTrigger asChild>
        <Button
          variant="ghost"
          size="sm"
          className="size-7 p-0"
          onClick={handleCheck}
          disabled={isCurrentlyChecking || disabled}
        >
          <AnimatePresence initial={false} mode="wait">
            <motion.span
              key={statusKey}
              initial={{ opacity: 0, scale: reduceMotion ? 1 : 0.9 }}
              animate={{
                opacity: 1,
                scale: 1,
                transition: {
                  duration: reduceMotion ? 0.15 : 0.16,
                  ease: MOTION_EASE_OUT,
                },
              }}
              exit={{
                opacity: 0,
                scale: reduceMotion ? 1 : 0.9,
                transition: {
                  duration: reduceMotion ? 0.15 : 0.1,
                  ease: MOTION_EASE_OUT,
                },
              }}
              className="inline-flex size-3 items-center justify-center"
            >
              {isCurrentlyChecking ? (
                <span className="size-3 animate-spin rounded-full border border-current border-t-transparent" />
              ) : result?.is_valid && result.country_code ? (
                <span className="relative inline-flex items-center justify-center">
                  <FlagIcon
                    countryCode={result.country_code}
                    className="h-2.5"
                  />
                  <FiCheck className="absolute right-[-4px] bottom-[-6px]" />
                </span>
              ) : result && !result.is_valid ? (
                <span className="text-sm text-destructive-text">✕</span>
              ) : (
                <FiCheck className="size-3" />
              )}
            </motion.span>
          </AnimatePresence>
        </Button>
      </TooltipTrigger>
      <TooltipContent>
        {isCurrentlyChecking ? (
          <p>{t("proxyCheck.tooltipChecking")}</p>
        ) : result?.is_valid ? (
          <div className="space-y-1">
            <p className="flex items-center gap-1">
              {result.country_code && (
                <FlagIcon countryCode={result.country_code} />
              )}
              {[result.city, result.country].filter(Boolean).join(", ") ||
                t("proxyCheck.unknownLocation")}
            </p>
            <p className="text-xs text-primary-foreground">
              {t("proxyCheck.tooltipIp", { ip: result.ip })}
            </p>
            <p className="text-xs text-primary-foreground">
              {t("proxyCheck.tooltipChecked", {
                time: formatRelativeTime(result.timestamp),
              })}
            </p>
          </div>
        ) : result && !result.is_valid ? (
          <div>
            <p>{t("proxyCheck.tooltipFailedTitle")}</p>
            <p className="text-xs text-primary-foreground">
              {t("proxyCheck.tooltipFailed", {
                time: formatRelativeTime(result.timestamp),
              })}
            </p>
          </div>
        ) : (
          <p>{t("proxyCheck.tooltipDefault")}</p>
        )}
      </TooltipContent>
    </Tooltip>
  );
}
