import { AxiosRequestConfig } from 'axios';
import { create } from 'zustand';

import { toast } from '@/components/ui/use-toast';
import { Contract, buildAgreementFromContract } from '@/utils/helpers/agreement-helpers';
import { ClientAgreementProps } from '@/utils/types/legal-agreements.types';


interface ApiClient {
  get: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>;
  post: <T, D = unknown>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig
  ) => Promise<T>;
  put: <T, D = unknown>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig
  ) => Promise<T>;
  patch: <T, D = unknown>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig
  ) => Promise<T>;
  delete: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>;
}

interface AgreementModalState {
  showModal: boolean;
  selectedAgreement: ClientAgreementProps | null;
  hasCheckedOnLogin: boolean;
  setShowModal: (show: boolean) => void;
  setSelectedAgreement: (agreement: ClientAgreementProps | null) => void;
  setHasCheckedOnLogin: (checked: boolean) => void;
  reset: () => void;
}

export const useAgreementModalStore = create<AgreementModalState>(set => ({
  showModal: false,
  selectedAgreement: null,
  hasCheckedOnLogin: false,
  setShowModal: show => set({ showModal: show }),
  setSelectedAgreement: agreement => set({ selectedAgreement: agreement }),
  setHasCheckedOnLogin: checked => set({ hasCheckedOnLogin: checked }),
  reset: () => set({ showModal: false, selectedAgreement: null, hasCheckedOnLogin: false }),
}));

interface AgreementPayload {
  name: string;
  type: string;
  agreement_signed: string;
  client_id: string | number;
  attachment_id?: number;
  contract_id: number;
}

// Helper functions to be used in components
export const acceptAgreement = async (
  agreement: ClientAgreementProps,
  api: ApiClient,
  clientId: string | number
): Promise<void> => {
  try {
    if (!clientId) {
      toast({
        title: 'Error',
        description: 'Client ID is missing.',
        // variant: 'destructive',
      });
      return;
    }
    const currentDate = new Date().toISOString().slice(0, 19).replace('T', ' ');
    const payload: AgreementPayload = {
      name: agreement?.name,
      type: agreement?.type,
      agreement_signed: currentDate,
      client_id: clientId,
      contract_id: agreement?.id,
    };

    // Only include attachment_id if it's a valid ID (greater than 0)
    if (agreement?.attachment?.id && agreement.attachment.id > 0) {
      payload.attachment_id = agreement.attachment.id;
    }

    // const response = await api.post<void>(
    //   '/customer/client-agreements',
    //   payload
    // );

    toast({
      title: 'Success',
      description: 'Agreement accepted successfully',
    });

    useAgreementModalStore.getState().reset();
  } catch (_error) {
    toast({
      title: 'Error',
      description: 'Failed to accept agreement',
      // variant: 'destructive',
    });
  }
};

export const checkPendingAgreements = async (
  api: ApiClient,
  clientId: string | number
): Promise<void> => {
  if (!clientId) return;

  const store = useAgreementModalStore.getState();


  const hasCheckedInSession = sessionStorage.getItem('hasCheckedAgreementsOnLogin');
  if (hasCheckedInSession === 'true') return;


  const lastLoginTimestamp = sessionStorage.getItem('userLoginTimestamp');
  const currentTime = Date.now();
  const timeSinceLastLogin = lastLoginTimestamp ? currentTime - parseInt(lastLoginTimestamp) : 0;

  if (timeSinceLastLogin < 10000 && lastLoginTimestamp) {

    sessionStorage.setItem('hasCheckedAgreementsOnLogin', 'true');
    return;
  }

  // Update the login timestamp
  sessionStorage.setItem('userLoginTimestamp', currentTime.toString());

  try {
    // Fetch contracts from contracts API
    const contractsResponse = await api.get<{ data: Contract[] }>('/customer/contracts');
    const allContracts = contractsResponse.data || [];

    // Fetch client agreements
    const agreementsResponse = await api.get<{ data: ClientAgreementProps[] }>(
      `/customer/clients/${clientId}/client-agreements`
    );
    const allClientAgreements = agreementsResponse.data || [];

    // Find contracts that exist in contracts API but not in client agreements API
    const signedAgreementContractIds = allClientAgreements.map((agreement: ClientAgreementProps) => agreement.contract?.id);

    const unsignedContracts = allContracts.filter(
      (contract: Contract) => !signedAgreementContractIds.includes(contract.id)
    );

    // If there are unsigned contracts, show the first one
    if (unsignedContracts.length > 0) {
      const firstUnsignedContract = unsignedContracts[0];
      // Convert contract to agreement format for consistency
      const agreementToShow = buildAgreementFromContract(firstUnsignedContract);

      store.setSelectedAgreement(agreementToShow);
      store.setShowModal(true);
    }

    // Mark that we've checked on this browser session
    sessionStorage.setItem('hasCheckedAgreementsOnLogin', 'true');
  } catch (_error) {
    toast({
      title: 'Error',
      description: 'Something went wrong!',
      // variant: 'destructive',
    });
  }
};
