"use client";

import { invoke } from "@tauri-apps/api/core";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
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 { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { useCloudAuth } from "@/hooks/use-cloud-auth";
import { showErrorToast, showSuccessToast } from "@/lib/toast-utils";
import type { BrowserProfile, SyncMode, SyncSettings } from "@/types";
import { isSyncEnabled } from "@/types";

interface ProfileSyncDialogProps {
  isOpen: boolean;
  onClose: () => void;
  profile: BrowserProfile | null;
  onSyncConfigOpen: () => void;
}

export function ProfileSyncDialog({
  isOpen,
  onClose,
  profile,
  onSyncConfigOpen,
}: ProfileSyncDialogProps) {
  const { t } = useTranslation();
  const { user: cloudUser } = useCloudAuth();
  const isCloudSyncEligible =
    cloudUser != null &&
    cloudUser.plan !== "free" &&
    (cloudUser.subscriptionStatus === "active" ||
      cloudUser.planPeriod === "lifetime");
  // Encryption available to everyone except team members who aren't owners
  const canUseEncryption =
    cloudUser == null ||
    cloudUser.plan !== "team" ||
    cloudUser.teamRole === "owner";
  const [isSaving, setIsSaving] = useState(false);
  const [isSyncing, setIsSyncing] = useState(false);
  const [syncMode, setSyncMode] = useState<SyncMode>(
    profile?.sync_mode ?? "Disabled",
  );
  const [hasSelfHostedConfig, setHasSelfHostedConfig] = useState(false);
  const [hasE2ePassword, setHasE2ePassword] = useState(false);
  const [isCheckingConfig, setIsCheckingConfig] = useState(false);
  const [userChangedMode, setUserChangedMode] = useState(false);

  const hasConfig = isCloudSyncEligible || hasSelfHostedConfig;

  const checkSyncConfig = useCallback(async () => {
    setIsCheckingConfig(true);
    try {
      const settings = await invoke<SyncSettings>("get_sync_settings");
      setHasSelfHostedConfig(
        Boolean(settings.sync_server_url && settings.sync_token),
      );
      const hasPassword = await invoke<boolean>("check_has_e2e_password");
      setHasE2ePassword(hasPassword);
    } catch {
      setHasSelfHostedConfig(false);
    } finally {
      setIsCheckingConfig(false);
    }
  }, []);

  useEffect(() => {
    if (isOpen && profile) {
      setSyncMode(profile.sync_mode ?? "Disabled");
      setUserChangedMode(false);
      void checkSyncConfig();
    }
  }, [isOpen, profile, checkSyncConfig]);

  const handleOpenChange = useCallback(
    (open: boolean) => {
      if (!open) {
        onClose();
      }
    },
    [onClose],
  );

  const handleModeChange = useCallback(
    async (newMode: string) => {
      if (!profile) return;

      if (!hasConfig) {
        showErrorToast(t("sync.mode.noPasswordWarning"));
        onSyncConfigOpen();
        onClose();
        return;
      }

      if (newMode === "Encrypted" && !canUseEncryption) {
        showErrorToast(t("settings.encryption.requiresProOrOwner"));
        return;
      }

      if (newMode === "Encrypted" && !hasE2ePassword) {
        showErrorToast(t("sync.mode.passwordRequired"));
        return;
      }

      setIsSaving(true);
      try {
        await invoke("set_profile_sync_mode", {
          profileId: profile.id,
          syncMode: newMode,
        });
        setSyncMode(newMode as SyncMode);
        setUserChangedMode(true);
        showSuccessToast(
          newMode !== "Disabled"
            ? t("sync.mode.enabledToast")
            : t("sync.mode.disabledToast"),
        );
      } catch (error) {
        console.error("Failed to set sync mode:", error);
        showErrorToast(String(error));
      } finally {
        setIsSaving(false);
      }
    },
    [
      profile,
      hasConfig,
      hasE2ePassword,
      canUseEncryption,
      onSyncConfigOpen,
      onClose,
      t,
    ],
  );

  const handleSyncNow = useCallback(async () => {
    if (!profile) return;

    if (!hasConfig) {
      showErrorToast(t("sync.mode.noPasswordWarning"));
      onSyncConfigOpen();
      onClose();
      return;
    }

    setIsSyncing(true);
    try {
      await invoke("request_profile_sync", { profileId: profile.id });
      showSuccessToast(t("sync.mode.syncQueued"));
    } catch (error) {
      console.error("Failed to queue sync:", error);
      showErrorToast(String(error));
    } finally {
      setIsSyncing(false);
    }
  }, [profile, hasConfig, onSyncConfigOpen, onClose, t]);

  const formatLastSync = (timestamp?: number) => {
    if (!timestamp) return t("common.labels.never");
    const date = new Date(timestamp * 1000);
    return date.toLocaleString();
  };

  if (!profile) return null;

  return (
    <Dialog open={isOpen} onOpenChange={handleOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>{t("sync.mode.title")}</DialogTitle>
          <DialogDescription>
            {t("sync.mode.description", {
              name: profile.name,
              defaultValue: `Manage sync settings for "${profile.name}"`,
            })}
          </DialogDescription>
        </DialogHeader>

        {isCheckingConfig ? (
          <div className="flex justify-center py-8">
            <div className="size-6 rounded-full border-2 border-current animate-spin border-t-transparent" />
          </div>
        ) : (
          <div className="grid gap-4 py-4">
            {!hasConfig && (
              <div className="p-3 text-sm rounded-md bg-muted">
                <p className="mb-2">{t("sync.mode.notConfigured")}</p>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    onSyncConfigOpen();
                    onClose();
                  }}
                >
                  {t("sync.mode.configureService")}
                </Button>
              </div>
            )}

            {hasConfig && (
              <>
                <RadioGroup
                  value={syncMode}
                  onValueChange={handleModeChange}
                  disabled={isSaving}
                  className="grid gap-3"
                >
                  <div className="flex items-start gap-x-3">
                    <RadioGroupItem value="Disabled" id="sync-disabled" />
                    <Label htmlFor="sync-disabled" className="cursor-pointer">
                      <span className="font-medium">
                        {t("sync.mode.disabled")}
                      </span>
                      <p className="text-sm text-muted-foreground">
                        {t("sync.mode.disabledDescription")}
                      </p>
                    </Label>
                  </div>

                  <div className="flex items-start gap-x-3">
                    <RadioGroupItem value="Regular" id="sync-regular" />
                    <Label htmlFor="sync-regular" className="cursor-pointer">
                      <span className="font-medium">
                        {t("sync.mode.regular")}
                      </span>
                      <p className="text-sm text-muted-foreground">
                        {t("sync.mode.regularDescription")}
                      </p>
                    </Label>
                  </div>

                  <div className="flex items-start gap-x-3">
                    <RadioGroupItem
                      value="Encrypted"
                      id="sync-encrypted"
                      disabled={!canUseEncryption}
                    />
                    <Label
                      htmlFor="sync-encrypted"
                      className={
                        canUseEncryption
                          ? "cursor-pointer"
                          : "cursor-not-allowed opacity-50"
                      }
                    >
                      <span className="font-medium">
                        {t("sync.mode.encrypted")}
                      </span>
                      <p className="text-sm text-muted-foreground">
                        {canUseEncryption
                          ? t("sync.mode.encryptedDescription")
                          : t("settings.encryption.requiresProOrOwner")}
                      </p>
                    </Label>
                  </div>
                </RadioGroup>

                {syncMode === "Encrypted" &&
                  !hasE2ePassword &&
                  userChangedMode && (
                    <div className="p-3 text-sm rounded-md bg-destructive/10 text-destructive">
                      {t("sync.mode.noPasswordWarning")}
                    </div>
                  )}

                <div className="space-y-2">
                  <Label>{t("sync.mode.lastSynced")}</Label>
                  <div className="flex gap-2 items-center">
                    <Badge variant="outline">
                      {formatLastSync(profile.last_sync)}
                    </Badge>
                    {isSyncEnabled(profile) && (
                      <Badge
                        variant={profile.last_sync ? "default" : "secondary"}
                      >
                        {profile.last_sync
                          ? t("common.status.synced")
                          : t("common.status.pending")}
                      </Badge>
                    )}
                  </div>
                </div>
              </>
            )}
          </div>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={onClose}>
            {t("common.buttons.close")}
          </Button>
          {hasConfig && isSyncEnabled(profile) && (
            <LoadingButton onClick={handleSyncNow} isLoading={isSyncing}>
              {t("sync.mode.syncNow")}
            </LoadingButton>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
