import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import { tenantService, type TenantResponse, type TenantAccessResponse } from '../api';
import { useAuthUser } from './auth.store';
import { TENANT_ROLES, GLOBAL_USER_ROLES } from '../types/roles';

export interface TenantState {
  // State
  currentTenant: TenantResponse | null;
  availableTenants: TenantResponse[] | null;
  currentTenantAccess: TenantAccessResponse | null;
  isLoading: boolean;
  error: string | null;
  
  // Actions
  setCurrentTenant: (tenant: TenantResponse) => void;
  switchTenant: (tenantId: string) => Promise<boolean>;
  loadUserTenants: () => Promise<void>;
  loadCurrentTenantAccess: () => Promise<void>;
  clearTenants: () => void;
  clearError: () => void;
  setLoading: (loading: boolean) => void;
  
  // Permission helpers (migrated from BakeryContext)
  hasPermission: (permission: string) => boolean;
  canAccess: (resource: string, action: string) => boolean;
}

export const useTenantStore = create<TenantState>()(
  persist(
    (set, get) => ({
      // Initial state
      currentTenant: null,
      availableTenants: null,
      currentTenantAccess: null,
      isLoading: false,
      error: null,

      // Actions
      setCurrentTenant: (tenant: TenantResponse) => {
        set({ currentTenant: tenant, currentTenantAccess: null });
        // Update API client with new tenant ID
        if (tenant) {
          tenantService.setCurrentTenant(tenant);
          // Load tenant access info
          get().loadCurrentTenantAccess();
        }
      },

      switchTenant: async (tenantId: string): Promise<boolean> => {
        try {
          set({ isLoading: true, error: null });
          
          const { availableTenants } = get();
          
          // Find tenant in available tenants
          const targetTenant = availableTenants?.find(t => t.id === tenantId);
          if (!targetTenant) {
            throw new Error('Tenant not found in available tenants');
          }
          
          // Switch tenant (frontend-only operation)
          get().setCurrentTenant(targetTenant);
          set({ isLoading: false });
          return true;
        } catch (error) {
          set({
            isLoading: false,
            error: error instanceof Error ? error.message : 'Failed to switch tenant',
          });
          return false;
        }
      },

      loadUserTenants: async (): Promise<void> => {
        try {
          set({ isLoading: true, error: null });
          
          // Get current user to determine user ID
          const authState = JSON.parse(localStorage.getItem('auth-storage') || '{}')?.state;
          const user = authState?.user;
          
          if (!user?.id) {
            throw new Error('User not authenticated');
          }
          
          const response = await tenantService.getUserTenants(user.id);
          
          if (response) {
            const tenants = Array.isArray(response) ? response : [response];
            
            set({ 
              availableTenants: tenants,
              isLoading: false 
            });
            
            // If no current tenant is set, set the first one as current
            const { currentTenant } = get();
            if (!currentTenant && tenants.length > 0) {
              get().setCurrentTenant(tenants[0]);
            }
          } else {
            // No tenants found - this is fine for users who haven't completed onboarding
            set({ 
              availableTenants: [],
              isLoading: false,
              error: null 
            });
          }
        } catch (error) {
          // Handle 404 gracefully - user might not have created any tenants yet
          if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
            set({
              availableTenants: [],
              isLoading: false,
              error: null,
            });
          } else {
            set({
              isLoading: false,
              error: error instanceof Error ? error.message : 'Failed to load tenants',
            });
          }
        }
      },

      loadCurrentTenantAccess: async (): Promise<void> => {
        try {
          const { currentTenant } = get();
          if (!currentTenant) return;

          const accessInfo = await tenantService.getCurrentUserTenantAccess(currentTenant.id);
          set({ currentTenantAccess: accessInfo });
        } catch (error) {
          // Don't set error state for access loading failures - just log
          console.warn('Failed to load tenant access:', error);
          set({ currentTenantAccess: null });
        }
      },

      clearTenants: () => {
        set({
          currentTenant: null,
          availableTenants: null,
          currentTenantAccess: null,
          error: null,
        });
        tenantService.clearCurrentTenant();
      },

      clearError: () => {
        set({ error: null });
      },

      setLoading: (loading: boolean) => {
        set({ isLoading: loading });
      },

      // Permission helpers (migrated from BakeryContext)
      hasPermission: (permission: string): boolean => {
        const { currentTenant, currentTenantAccess } = get();
        if (!currentTenant || !currentTenantAccess || !currentTenantAccess.has_access) {
          return false;
        }
        
        // Check if user has specific permission in their tenant permissions array
        if (currentTenantAccess.permissions?.includes(permission)) {
          return true;
        }
        
        // Check if user has broader permissions that include this one
        if (currentTenantAccess.permissions?.includes('*') || 
            currentTenantAccess.permissions?.includes('admin')) {
          return true;
        }
        
        // Role-based fallback for common permissions based on tenant role
        const tenantRole = currentTenantAccess.role;
        switch (tenantRole) {
          case TENANT_ROLES.OWNER:
          case TENANT_ROLES.ADMIN:
            return true;
          case TENANT_ROLES.MEMBER:
            // Members can read and write but not delete or manage users
            return !permission.includes('delete') && !permission.includes('admin');
          case TENANT_ROLES.VIEWER:
            // Viewers can only read
            return permission.includes('read') || permission.includes('view');
          default:
            return false;
        }
      },

      canAccess: (resource: string, action: string): boolean => {
        const { hasPermission } = get();
        
        // Check specific permission
        if (hasPermission(`${resource}:${action}`)) return true;
        
        // Check wildcard permissions
        if (hasPermission(`${resource}:*`)) return true;
        
        return false;
      },
    }),
    {
      name: 'tenant-storage',
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({
        currentTenant: state.currentTenant,
        availableTenants: state.availableTenants,
        currentTenantAccess: state.currentTenantAccess,
      }),
      onRehydrateStorage: () => (state) => {
        // Initialize API client with stored tenant when store rehydrates
        if (state?.currentTenant) {
          import('../api').then(({ apiClient }) => {
            apiClient.setTenantId(state.currentTenant!.id);
          });
        }
      },
    }
  )
);

// Selectors for common use cases
// Note: For getting tenant ID, prefer using useTenantId() from hooks/useTenantId.ts
export const useCurrentTenant = () => useTenantStore((state) => state.currentTenant);
export const useAvailableTenants = () => useTenantStore((state) => state.availableTenants);
export const useCurrentTenantAccess = () => useTenantStore((state) => state.currentTenantAccess);
export const useTenantLoading = () => useTenantStore((state) => state.isLoading);
export const useTenantError = () => useTenantStore((state) => state.error);

// Hook for tenant actions
export const useTenantActions = () => useTenantStore((state) => ({
  setCurrentTenant: state.setCurrentTenant,
  switchTenant: state.switchTenant,
  loadUserTenants: state.loadUserTenants,
  loadCurrentTenantAccess: state.loadCurrentTenantAccess,
  clearTenants: state.clearTenants,
  clearError: state.clearError,
  setLoading: state.setLoading,
}));

// Hook for tenant permissions (replaces useBakeryPermissions)
export const useTenantPermissions = () => useTenantStore((state) => ({
  hasPermission: state.hasPermission,
  canAccess: state.canAccess,
}));

// Combined hook for convenience
export const useTenant = () => {
  const currentTenant = useCurrentTenant();
  const availableTenants = useAvailableTenants();
  const currentTenantAccess = useCurrentTenantAccess();
  const isLoading = useTenantLoading();
  const error = useTenantError();
  const actions = useTenantActions();
  const permissions = useTenantPermissions();
  
  return {
    currentTenant,
    availableTenants,
    currentTenantAccess,
    isLoading,
    error,
    ...actions,
    ...permissions,
  };
};