import React, {
  createContext,
  Dispatch,
  ReactNode,
  SetStateAction,
  useContext,
  useState,
} from 'react';

import { getUser } from '../service/user/user.service';
import {
  IAverageOrderValue,
  IAverageThroughRecommendation,
  IConversionRate,
  IMetricRequest,
  IUser,
  IVisitorBehaviourHeader,
} from '../types';
import { OnboardingStatus } from '../components/OnboardingBanner';
import { recomaze_ai_personalization_env } from '../env';
import {
  average_order_value,
  average_through_recommendation,
  conversion_rate,
  unique_fingerprint,
  visits_behaviour_headers,
} from '../service/dashboard/dashboard.service';
import type { IJobStatusData } from '../service/ai-readiness/ai-readiness.interface';

interface LogEntry {
  timestamp: string;
  message: string;
  type: 'info' | 'success' | 'error';
}

export interface AiReadinessJobState {
  jobId: string;
  status: IJobStatusData;
  logs: LogEntry[];
}

interface ContextProps {
  user: IUser | null;
  token: string | null;
  clientId: string | null;
  editVoucher: any;
  canUseWpApi: boolean;
  showRatingPopup: boolean;
  setShowRatingPopup: Dispatch<SetStateAction<boolean>>;
  fetchUser: () => Promise<void>;
  setUser: Dispatch<SetStateAction<IUser | null>>;
  setCanUseWpApi: Dispatch<SetStateAction<boolean>>;
  setToken: Dispatch<SetStateAction<any>>;
  setEditVoucher: Dispatch<SetStateAction<any>>;
  setClientId: Dispatch<SetStateAction<any>>;

  shopData: any | null;
  setShopData: (shopData: any | null) => void;

  showRatingPopUp: boolean;
  setShowRatingPopUp: (show: boolean) => void;

  uniqueFingerprints: number | null;
  setUniqueFingerprints: (uniqueFingerprints: number | null) => void;

  visitorBehaviourHeader: IVisitorBehaviourHeader | null;
  setVisitorBehaviourHeader: (
    visitorBehaviourHeader: IVisitorBehaviourHeader | null
  ) => void;

  conversionRate: IConversionRate | null;
  setConversionRate: (conversionRate: IConversionRate | null) => void;

  averageOrderValue: IAverageOrderValue | null;
  setAverageOrderValue: (averageOrderValue: IAverageOrderValue | null) => void;

  averageThroughRecommendation: IAverageThroughRecommendation | null;
  setAverageThroughRecommendation: (
    averageThroughRecommendation: IAverageThroughRecommendation | null
  ) => void;

  getFingerprint: (params: IMetricRequest) => Promise<void>;
  getVisitorBehaviorHeaders: (params: IMetricRequest) => Promise<void>;
  getAverageThroughRecomendation: (params: IMetricRequest) => Promise<void>;
  getConversionRate: (params: IMetricRequest) => Promise<void>;
  getAverageOrderValue: (params: IMetricRequest) => Promise<void>;

  onboarding: OnboardingStatus | null;
  setOnboarding: Dispatch<SetStateAction<OnboardingStatus | null>>;
  fetchOnboarding: () => Promise<void>;
  completeOnboardingStep: (
    step: 'dashboard' | 'customize' | 'audit' | 'preview',
    value?: boolean
  ) => Promise<void>;

  aiReadinessJob: AiReadinessJobState | null;
  setAiReadinessJob: Dispatch<SetStateAction<AiReadinessJobState | null>>;
}

const AppStateContext: React.Context<ContextProps> =
  createContext<ContextProps>({
    user: null,
    token: null,
    clientId: null,
    editVoucher: null,
    showRatingPopup: false,
    canUseWpApi: true,
    setCanUseWpApi: () => null,
    setShowRatingPopup: () => null,
    setUser: () => null,
    setEditVoucher: () => null,
    setToken: () => null,
    setClientId: () => null,
    fetchUser: async () => {},

    shopData: null,
    setShopData: () => {},

    showRatingPopUp: false,
    setShowRatingPopUp: () => {},

    uniqueFingerprints: null,
    setUniqueFingerprints: () => {},

    visitorBehaviourHeader: null,
    setVisitorBehaviourHeader: () => {},

    conversionRate: null,
    setConversionRate: () => {},

    averageThroughRecommendation: null,
    setAverageThroughRecommendation: () => {},

    averageOrderValue: null,
    setAverageOrderValue: () => {},

    getFingerprint: async () => {},
    getConversionRate: async () => {},
    getVisitorBehaviorHeaders: async () => {},
    getAverageThroughRecomendation: async () => {},
    getAverageOrderValue: async () => {},

    onboarding: null,
    setOnboarding: () => {},
    fetchOnboarding: async () => {},
    completeOnboardingStep: async () => {},

    aiReadinessJob: null,
    setAiReadinessJob: () => {},
  });

export const useAppStateContext = () => useContext(AppStateContext);

type Props = { children: ReactNode };

export const AppStateProvider = ({ children }: Props) => {
  const [user, setUser] = useState<IUser | null>(null);
  const [token, setToken] = useState(null);

  const [clientId, setClientId] = useState(null);
  const [canUseWpApi, setCanUseWpApi] = useState<boolean>(true);
  const [editVoucher, setEditVoucher] = useState<any | null>(null);
  const [showRatingPopup, setShowRatingPopup] = useState(false);

  const [shopData, setShopData] = useState<any | null>(null);
  const [showRatingPopUp, setShowRatingPopUp] = useState<boolean>(false);

  const [uniqueFingerprints, setUniqueFingerprints] = useState<number | null>(
    null
  );
  const [visitorBehaviourHeader, setVisitorBehaviourHeader] =
    useState<IVisitorBehaviourHeader | null>(null);

  const [averageThroughRecommendation, setAverageThroughRecommendation] =
    useState<IAverageThroughRecommendation | null>(null);

  const [conversionRate, setConversionRate] = useState<IConversionRate | null>(
    null
  );

  const [averageOrderValue, setAverageOrderValue] =
    useState<IAverageOrderValue | null>(null);

  const [onboarding, setOnboarding] = useState<OnboardingStatus | null>(null);

  const [aiReadinessJob, setAiReadinessJob] =
    useState<AiReadinessJobState | null>(null);

  /**
   * Fetch onboarding status from WP REST API.
   * @return {Promise<void>}
   */
  const fetchOnboarding = async (): Promise<void> => {
    try {
      if (!recomaze_ai_personalization_env?.can_use_wp_api) return;

      const response = await fetch(
        `${recomaze_ai_personalization_env?.wp_api_url}recomaze/v1/onboarding`,
        {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': recomaze_ai_personalization_env?.nonce || '',
          },
        }
      );
      const data = await response.json();
      if (data?.success) {
        setOnboarding({
          dashboard_visited: data.dashboard_visited,
          popup_customized: data.popup_customized,
          audit_completed: data.audit_completed,
          show_preview_banner: data.show_preview_banner,
        });
      }
    } catch (error) {
      console.error('fetchOnboarding error:', error);
    }
  };

  /**
   * Complete an onboarding step.
   * @param step Step name.
   * @param value Optional value (defaults to true, can be used for toggling preview).
   * @return {Promise<void>}
   */
  const completeOnboardingStep = async (
    step: 'dashboard' | 'customize' | 'audit' | 'preview',
    value: boolean = true
  ): Promise<void> => {
    try {
      if (!recomaze_ai_personalization_env?.can_use_wp_api) return;

      const response = await fetch(
        `${recomaze_ai_personalization_env?.wp_api_url}recomaze/v1/onboarding`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': recomaze_ai_personalization_env?.nonce || '',
          },
          body: JSON.stringify({ step, value }),
        }
      );
      const data = await response.json();
      if (data?.success) {
        setOnboarding({
          dashboard_visited: data.dashboard_visited,
          popup_customized: data.popup_customized,
          audit_completed: data.audit_completed,
          show_preview_banner: data.show_preview_banner,
        });
      }
    } catch (error) {
      console.error('completeOnboardingStep error:', error);
    }
  };

  /**
   * @return {Promise<void>}
   */
  const fetchUser = async (): Promise<void> => {
    try {
      const response: any = await getUser();
      if (response?.success) setUser(response);
    } catch (error) {
      console.log(error);
    }
  };
  const getFingerprint = async ({ endDate, startDate }: IMetricRequest) => {
    try {
      const response = await unique_fingerprint({ endDate, startDate });
      if (response?.data?.unique_fingerprints) {
        setUniqueFingerprints(response.data.unique_fingerprints);
      }
    } catch (error) {
      console.error('getFingerprint error:', error);
    }
  };

  const getVisitorBehaviorHeaders = async ({
    endDate,
    startDate,
  }: IMetricRequest) => {
    try {
      const response = await visits_behaviour_headers({
        end: endDate,
        start: startDate,
      });
      if (response?.data) {
        setVisitorBehaviourHeader(response.data);
      }
    } catch (error) {
      console.error('getVisitorBehaviorHeaders error:', error);
    }
  };

  const getAverageThroughRecomendation = async ({
    endDate,
    startDate,
  }: IMetricRequest) => {
    try {
      const response = await average_through_recommendation({
        endDate,
        startDate,
      });
      if (response?.data) {
        setAverageThroughRecommendation(response.data);
      }
    } catch (error) {
      console.error('average recommendation error:', error);
    }
  };

  const getConversionRate = async ({ endDate, startDate }: IMetricRequest) => {
    try {
      const response = await conversion_rate({
        endDate,
        startDate,
      });
      if (response?.data) {
        setConversionRate(response.data);
      }
    } catch (error) {
      console.error('conversion rate error:', error);
    }
  };

  const getAverageOrderValue = async ({
    endDate,
    startDate,
  }: IMetricRequest) => {
    try {
      const response = await average_order_value({
        endDate,
        startDate,
      });

      if (response?.data) {
        setAverageOrderValue(response.data);
      }
    } catch (error) {
      console.error('conversion rate error:', error);
    }
  };

  return (
    <AppStateContext.Provider
      value={{
        user,
        token,
        clientId,
        editVoucher,
        showRatingPopup,
        setShowRatingPopup,
        setEditVoucher,
        setUser,
        setToken,
        fetchUser,
        setClientId,
        shopData,
        setShopData,
        showRatingPopUp,
        setShowRatingPopUp,
        uniqueFingerprints,
        setUniqueFingerprints,
        visitorBehaviourHeader,
        setVisitorBehaviourHeader,
        averageThroughRecommendation,
        conversionRate,
        setConversionRate,
        getConversionRate,
        averageOrderValue,
        getAverageOrderValue,
        setAverageOrderValue,
        setAverageThroughRecommendation,
        getFingerprint,
        getVisitorBehaviorHeaders,
        getAverageThroughRecomendation,
        canUseWpApi,
        setCanUseWpApi,
        onboarding,
        setOnboarding,
        fetchOnboarding,
        completeOnboardingStep,
        aiReadinessJob,
        setAiReadinessJob,
      }}
    >
      {children}
    </AppStateContext.Provider>
  );
};
