import { MutableRefObject, useCallback } from 'react';
import type { NavigateFunction } from 'react-router-dom';
import type { FolderId, TenantId } from '../../types/identifiers';

interface ApiClient {
  get: (path: string) => Promise<{ data: unknown }>;
  post: (path: string, body?: unknown) => Promise<{ data: any }>;
  defaults: { headers: { common: Record<string, unknown> } };
}

interface TenantOption {
  id?: TenantId;
  name?: string;
}

interface UseTenantManagerOptions {
  apiClient: ApiClient;
  appDispatch: (action: any) => void;
  currentTenantId: TenantId | null;
  resetWorkspaceState: () => void;
  setStatusMessage: (message: string, variant?: string) => void;
  notifyApiError: (error: unknown, message: string) => void;
  refreshTags: () => Promise<void>;
  refreshCorrespondents: () => Promise<void>;
  loadFolder: (folderId: FolderId, options?: { preserveSearch?: boolean }) => Promise<void>;
  handleDocumentsViewModeChange: (mode: string) => void;
  navigate: NavigateFunction;
  tokenRef?: MutableRefObject<string | null>;
  tenantIdRef?: MutableRefObject<TenantId | null>;
}

const useTenantManager = ({
  apiClient,
  appDispatch,
  currentTenantId,
  resetWorkspaceState,
  setStatusMessage,
  notifyApiError,
  refreshTags,
  refreshCorrespondents,
  loadFolder,
  handleDocumentsViewModeChange,
  navigate,
  tokenRef,
  tenantIdRef,
}: UseTenantManagerOptions) => {
  const handleTenantSelect = useCallback(
    async (tenantOption: TenantOption | null, { refreshOnly = false }: { refreshOnly?: boolean } = {}) => {
      const requestedTenantId = tenantOption?.id ?? null;
      if (!refreshOnly && (!requestedTenantId || requestedTenantId === currentTenantId)) {
        return;
      }

      try {
        if (!refreshOnly) {
          setStatusMessage('Switching tenant…', 'info');
        }

        if (refreshOnly) {
          const { data } = await apiClient.get('/tenants');
          appDispatch({
            type: 'SET_TENANTS',
            tenants: Array.isArray(data) ? data : [],
          });
          return;
        }

        const { data } = await apiClient.post('/auth/select-tenant', {
          tenant_id: requestedTenantId,
        });
        if (!data?.access_token) {
          throw new Error('Missing access token in tenant switch response.');
        }

        appDispatch({ type: 'LOGOUT' });
        resetWorkspaceState();

        appDispatch({
          type: 'LOGIN_SUCCESS',
          token: data.access_token,
          tenant: data.tenant || null,
        });

        apiClient.defaults.headers.common.Authorization = `Bearer ${data.access_token}`;
        if (tokenRef) {
          tokenRef.current = data.access_token;
        }
        if (tenantIdRef) {
          tenantIdRef.current = data?.tenant?.id ?? null;
        }

        if (Array.isArray(data?.tenants)) {
          appDispatch({ type: 'SET_TENANTS', tenants: data.tenants });
        }

        handleDocumentsViewModeChange('list');
        navigate('/documents', { replace: true });

        await Promise.all([refreshTags(), refreshCorrespondents()]);
        await loadFolder('root', { preserveSearch: false });

        const tenantLabel = data?.tenant?.name || data?.tenant?.id || 'tenant';
        setStatusMessage(`Switched to ${tenantLabel}.`, 'info');
      } catch (error) {
        notifyApiError(error, 'Failed to switch tenant.');
      }
    },
    [
      apiClient,
      appDispatch,
      currentTenantId,
      handleDocumentsViewModeChange,
      loadFolder,
      navigate,
      notifyApiError,
      refreshCorrespondents,
      refreshTags,
      resetWorkspaceState,
      setStatusMessage,
      tenantIdRef,
      tokenRef,
    ],
  );

  return { handleTenantSelect };
};

export default useTenantManager;
