import { useState, useCallback, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { secretService } from '#features/functions/services/secret.service';
import type { SecretSchema, CreateSecretRequest } from '@insforge/shared-schemas';
import { useToast } from '@insforge/ui';
import { useConfirm } from '#lib/hooks/useConfirm';

export function useSecretValue(secret: Pick<SecretSchema, 'key' | 'updatedAt'>) {
  const { showToast } = useToast();
  const updatedAtKey = secret.updatedAt ?? 'never';
  const [isValueVisible, setIsValueVisible] = useState(false);
  const [valueError, setValueError] = useState<string | null>(null);

  useEffect(() => {
    setIsValueVisible(false);
    setValueError(null);
  }, [secret.key, updatedAtKey]);

  const {
    data: revealedSecret,
    isFetching: isFetchingValue,
    refetch: refetchSecretValue,
  } = useQuery({
    queryKey: ['secret-value', secret.key, updatedAtKey],
    queryFn: () => secretService.getSecretValue(secret.key),
    enabled: false,
    retry: false,
  });

  const toggleValue = useCallback(async () => {
    if (isValueVisible) {
      setIsValueVisible(false);
      return;
    }

    setValueError(null);

    if (!revealedSecret) {
      const { data, error } = await refetchSecretValue();

      if (error || !data) {
        const errorMessage =
          error instanceof Error ? error.message : 'Failed to fetch secret value';
        setValueError(errorMessage);
        showToast(errorMessage, 'error');
        return;
      }
    }

    setIsValueVisible(true);
  }, [isValueVisible, revealedSecret, refetchSecretValue, showToast]);

  return {
    isValueVisible,
    valueError,
    revealedSecret,
    isFetchingValue,
    toggleValue,
  };
}

export function useSecrets() {
  const queryClient = useQueryClient();
  const { showToast } = useToast();
  const { confirm, confirmDialogProps } = useConfirm();
  const [searchQuery, setSearchQuery] = useState('');

  // Query to fetch all secrets
  const {
    data: allSecrets = [],
    isLoading,
    error,
    refetch,
  } = useQuery({
    queryKey: ['secrets'],
    queryFn: () => secretService.listSecrets(),
    staleTime: 2 * 60 * 1000, // Cache for 2 minutes
  });

  // Filter out inactive secrets
  const secrets = allSecrets.filter((secret: SecretSchema) => secret.isActive);

  // Create secret mutation
  const createSecretMutation = useMutation({
    mutationFn: (input: CreateSecretRequest) => secretService.createSecret(input),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['secrets'] });
      showToast('Secret created successfully', 'success');
    },
    onError: (error: Error) => {
      console.error('Failed to create secret:', error);
      const errorMessage = error instanceof Error ? error.message : 'Failed to create secret';
      showToast(errorMessage, 'error');
    },
  });

  // Delete secret mutation
  const deleteSecretMutation = useMutation({
    mutationFn: (key: string) => secretService.deleteSecret(key),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['secrets'] });
      showToast('Secret deleted successfully', 'success');
    },
    onError: (error: Error) => {
      console.error('Failed to delete secret:', error);
      const errorMessage = error instanceof Error ? error.message : 'Failed to delete secret';
      showToast(errorMessage, 'error');
    },
  });

  // Create secret with validation
  const createSecret = useCallback(
    async (key: string, value: string) => {
      if (!key.trim() || !value.trim()) {
        showToast('Please fill in both key and value', 'error');
        return false;
      }

      try {
        await createSecretMutation.mutateAsync({
          key: key.trim(),
          value: value.trim(),
        });
        return true;
      } catch {
        return false;
      }
    },
    [createSecretMutation, showToast]
  );

  // Delete secret with confirmation
  const deleteSecret = useCallback(
    async (secret: SecretSchema) => {
      if (secret.isReserved) {
        showToast('Cannot delete reserved secrets', 'error');
        return false;
      }

      const shouldDelete = await confirm({
        title: 'Delete Secret',
        description: `You sure to delete "${secret.key}"?`,
        confirmText: 'Delete',
        cancelText: 'Cancel',
        destructive: true,
      });

      if (shouldDelete) {
        try {
          await deleteSecretMutation.mutateAsync(secret.key);
          return true;
        } catch {
          return false;
        }
      }
      return false;
    },
    [confirm, deleteSecretMutation, showToast]
  );

  // Filter secrets based on search query
  const filteredSecrets = secrets.filter((secret: SecretSchema) =>
    secret.key.toLowerCase().includes(searchQuery.toLowerCase())
  );

  return {
    // Data
    secrets,
    filteredSecrets,
    secretsCount: secrets.length,
    searchQuery,

    // Loading states
    isLoading,
    isCreating: createSecretMutation.isPending,
    isDeleting: deleteSecretMutation.isPending,

    // Error
    error,

    // Actions
    createSecret,
    deleteSecret,
    setSearchQuery,
    refetch,

    // Confirm dialog props
    confirmDialogProps,
  };
}
