/**
 * Staff Invitations Management Hooks
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import apiClient from '../api/client';

export interface StaffInvitation {
  id: number;
  email: string;
  role: 'TENANT_MANAGER' | 'TENANT_STAFF';
  role_display: string;
  status: 'PENDING' | 'ACCEPTED' | 'DECLINED' | 'EXPIRED' | 'CANCELLED';
  invited_by: number | null;
  invited_by_name: string | null;
  created_at: string;
  expires_at: string;
  accepted_at: string | null;
  create_bookable_resource: boolean;
  resource_name: string;
  permissions: Record<string, boolean>;
  staff_role_id: number | null;
  staff_role_name: string | null;
}

export interface InvitationDetails {
  email: string;
  role: string;
  role_display: string;
  business_name: string;
  invited_by: string | null;
  expires_at: string;
  create_bookable_resource?: boolean;
  resource_name?: string;
  invitation_type?: 'tenant' | 'staff';
}

export interface StaffPermissions {
  // Manager permissions
  can_invite_staff?: boolean;
  can_manage_resources?: boolean;
  can_manage_services?: boolean;
  can_view_reports?: boolean;
  can_access_settings?: boolean;
  can_refund_payments?: boolean;
  // Staff permissions
  can_view_all_schedules?: boolean;
  can_manage_own_appointments?: boolean;
}

export interface CreateInvitationData {
  email: string;
  role: 'TENANT_MANAGER' | 'TENANT_STAFF';
  create_bookable_resource?: boolean;
  resource_name?: string;
  permissions?: StaffPermissions;
  staff_role_id?: number | null;
}

/**
 * Hook to fetch pending invitations for the current business
 */
export const useInvitations = () => {
  return useQuery<StaffInvitation[]>({
    queryKey: ['invitations'],
    queryFn: async () => {
      const { data } = await apiClient.get('/staff/invitations/');
      return data;
    },
  });
};

/**
 * Hook to create a new staff invitation
 */
export const useCreateInvitation = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (invitationData: CreateInvitationData) => {
      const { data } = await apiClient.post('/staff/invitations/', invitationData);
      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['invitations'] });
    },
  });
};

/**
 * Hook to cancel a pending invitation
 */
export const useCancelInvitation = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (invitationId: number) => {
      await apiClient.delete(`/staff/invitations/${invitationId}/`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['invitations'] });
    },
  });
};

/**
 * Hook to resend an invitation email
 */
export const useResendInvitation = () => {
  return useMutation({
    mutationFn: async (invitationId: number) => {
      const { data } = await apiClient.post(`/staff/invitations/${invitationId}/resend/`);
      return data;
    },
  });
};

/**
 * Hook to get invitation details by token (for acceptance page)
 * Tries platform tenant invitations first, then falls back to staff invitations
 */
export const useInvitationDetails = (token: string | null) => {
  return useQuery<InvitationDetails>({
    queryKey: ['invitation', token],
    queryFn: async () => {
      // Try platform tenant invitation first
      try {
        const { data } = await apiClient.get(`/platform/tenant-invitations/token/${token}/`);
        return { ...data, invitation_type: 'tenant' };
      } catch {
        // Fall back to staff invitation
        const { data } = await apiClient.get(`/staff/invitations/token/${token}/`);
        return { ...data, invitation_type: 'staff' };
      }
    },
    enabled: !!token,
    retry: false,
  });
};

/**
 * Hook to accept an invitation
 * Tries platform tenant invitation first, then falls back to staff invitation
 */
export const useAcceptInvitation = () => {
  return useMutation({
    mutationFn: async ({
      token,
      firstName,
      lastName,
      password,
      invitationType,
    }: {
      token: string;
      firstName: string;
      lastName: string;
      password: string;
      invitationType?: 'tenant' | 'staff';
    }) => {
      const payload = {
        first_name: firstName,
        last_name: lastName,
        password,
      };

      // Use known invitation type if provided, otherwise try tenant first
      if (invitationType === 'staff') {
        const { data } = await apiClient.post(`/staff/invitations/token/${token}/accept/`, payload);
        return data;
      }

      try {
        const { data } = await apiClient.post(`/platform/tenant-invitations/token/${token}/accept/`, payload);
        return data;
      } catch {
        const { data } = await apiClient.post(`/staff/invitations/token/${token}/accept/`, payload);
        return data;
      }
    },
  });
};

/**
 * Hook to decline an invitation
 * Note: Platform tenant invitations may not have a decline endpoint
 */
export const useDeclineInvitation = () => {
  return useMutation({
    mutationFn: async ({ token, invitationType }: { token: string; invitationType?: 'tenant' | 'staff' }) => {
      if (invitationType === 'tenant') {
        // Platform tenant invitations - check if decline endpoint exists
        try {
          const { data } = await apiClient.post(`/platform/tenant-invitations/token/${token}/decline/`);
          return data;
        } catch {
          // May not have decline endpoint, just return success
          return { status: 'declined' };
        }
      }
      const { data } = await apiClient.post(`/staff/invitations/token/${token}/decline/`);
      return data;
    },
  });
};
