import config, { getSDKConfig } from "config";
import { EXPERIENCE_TYPE } from "redux/Experience/types";

import { PhoneNumberService } from "@komi-app/sms-sdk";
import { FLAGS, isOn } from "@komi-app/flags-sdk";
import { Edcm, EdcmService } from "@komi-app/edcm-sdk";
import { Campaigns, Sms, SystemTemplates } from "@komi-app/messaging-sdk";
import { CustomTags, Products } from "@komi-app/fans-sdk";

import AnalyticsApi from "./api/analytics.api";
import AuthApi from "./api/auth.api";
import bandsintownApi from "./api/bandsintown.api";
import GoogleApi from "./api/google.api";
import { MessagingAdaptor } from "./api/messaging-adaptor";
import RyeAPI from "./api/rye.api";
import shopMyShelfApi from "./api/shop-my-shelf.api";
import spotifyApi from "./api/spotify.api";
import BookingFactoryService from "./booking/BookingFactoryService";
import ExperienceFactoryService from "./experience/ExperienceFactoryService";
import AWSService from "./externals/AWSService";
import AffiliateService from "./AffiliateService";
import AnalyticsChartService from "./AnalyticsChartService";
import AnalyticsService from "./AnalyticsService";
import { Api } from "./api";
import AuthService from "./AuthService";
import AvailabilityRuleService from "./AvailabilityRuleService";
import BandsintownService from "./BandsintownService";
import CampaignService from "./CampaignService";
import CampaignTemplateService from "./CampaignTemplateService";
import CategoryService from "./CategoryService";
import CelloService from "./CelloService";
import DigitalProductService from "./DigitalProductService";
import DspService from "./DspService";
import EmailDomainService from "./EmailDomainService";
import FanGeoAggService from "./FanGeoAggService";
import { FanGeoAggServiceV1 } from "./FanGeoAggServiceV1";
import FansService from "./FansService";
import { FansServiceV1 } from "./FansServiceV1";
import FirebaseService from "./FirebaseService";
import IAPService from "./IAPService";
import LinkRedirectService from "./LinkRedirectService";
import LinkRedirectServiceV1 from "./LinkRedirectServiceV1";
import PayoutService from "./PayoutService";
import PhotoService from "./PhotoService";
import ProductService from "./ProductService";
import PurchasingOptionsService from "./PurchasingOptionsService";
import RyeShopifyService from "./ryeShopifyServices";
import SalesService, { SalesServiceInterface } from "./SalesService";
import SalesServiceV1 from "./SalesServiceV1";
import SeatedService from "./SeatedService";
import SegmentService from "./SegmentService";
import { SegmentServiceV1 } from "./SegmentServiceV1";
import SequenceLocationService from "./SequenceLocationService";
import ShopifyService from "./ShopifyService";
import ShopifyServiceV1 from "./ShopifyServiceV1";
import ShopMyShelfService from "./ShopMyShelfService";
import ShortVideoService from "./ShortVideoService";
import SpecialRequestService from "./SpecialRequestService";
import SpotifyService from "./SpotifyService";
import TagService from "./TagService";
import TalentService from "./TalentService";
import TalentServiceV1 from "./TalentServiceV1";
import TemplateService from "./TemplateService";
import TimeRangeService from "./TimeRangeService";
import UserService from "./UserService";
import { IVideoService, VideoService } from "./VideoService";

export const Apisauce = new Api();
export const AnalyticsApiSauce = new AnalyticsApi();
export const AuthApiSauce = new AuthApi();
export const googleApi = new GoogleApi();
export const messagingAdaptor = new MessagingAdaptor();

Apisauce.setup();
AnalyticsApiSauce.setup();

let talentServiceV1: TalentServiceV1
let shopifyServiceV1: ShopifyServiceV1
let salesServiceV1: SalesServiceV1
let ryeShopifyServiceV1: RyeShopifyService
let affiliateService: AffiliateService
let celloService: CelloService
let fanGeoAggServiceV1: FanGeoAggServiceV1
let fansServiceV1: FansServiceV1
let linkRedirectServiceV1: LinkRedirectServiceV1
let productsSDK: Products
let phoneNumberService: PhoneNumberService
let smsService: Sms
let campaignSDK: Campaigns
let systemTemplatesSDK: SystemTemplates
let customTagsSDK: CustomTags
let edcm: EdcmService
let digitalProductService: DigitalProductService
let segmentServiceV1: SegmentServiceV1
let shortVideoService: ShortVideoService
let analyticsService: AnalyticsService;
export const authService = new AuthService(Apisauce);
export const spotifyService = new SpotifyService(spotifyApi);
export const bandsintownService = new BandsintownService(bandsintownApi);
export const shopMyShelfService = new ShopMyShelfService(shopMyShelfApi);
export const talentServiceLegacy = new TalentService(Apisauce);
// export const talentServiceV1 = new TalentServiceV1(Apisauce);
export const getTalentServiceV1 = () => (talentServiceV1 || (talentServiceV1 = new TalentServiceV1(Apisauce)));
export const userService = new UserService(Apisauce);
export const salesServiceLegacy = new SalesService(Apisauce);
export const getSalesServiceV1 = () => (salesServiceV1 || (salesServiceV1 = new SalesServiceV1()));
export const campaignService = new CampaignService(Apisauce, messagingAdaptor);
export const templateService = new TemplateService(Apisauce, messagingAdaptor);
export const campaignTemplateService = new CampaignTemplateService(
  Apisauce,
  messagingAdaptor,
);
export const shopifyService = new ShopifyService(Apisauce);
// export const shopifyServiceV1 = new ShopifyServiceV1(Apisauce);
export const getShopifyServiceV1 = () => (shopifyServiceV1 || (shopifyServiceV1 = new ShopifyServiceV1(Apisauce)));
const ryeApi = new RyeAPI(shopifyService);
export const ryeShopifyServiceLegacy = new RyeShopifyService(
  ryeApi,
  shopifyService,
);
// export const ryeShopifyServiceV1 = new RyeShopifyService(
//   ryeApi,
//   shopifyServiceV1,
// );

export const getRyeShopifyServiceV1 = () => (
  ryeShopifyServiceV1
  ||
    (
      ryeShopifyServiceV1 = new RyeShopifyService(
        ryeApi,
        getShopifyServiceV1())
    )
)

export const seatedService = new SeatedService(Apisauce);
export const segmentServiceLegacy = new SegmentService(Apisauce);
export const getSegmentServiceV1 = () => (segmentServiceV1 || (segmentServiceV1 = new SegmentServiceV1()));
export const fansServiceLegacy = new FansService(Apisauce);
export const getFansServiceV1 = () => (fansServiceV1 || (fansServiceV1 = new FansServiceV1()));
export const linkRedirectServiceLegacy = new LinkRedirectService(Apisauce);
export const getLinkRedirectServiceV1 = () => (linkRedirectServiceV1 || (linkRedirectServiceV1 = new LinkRedirectServiceV1()));
export const emailDomainService = new EmailDomainService(
  Apisauce,
  messagingAdaptor,
);
export const sequenceLocationService = new SequenceLocationService(Apisauce);
export const fanGeoAggServiceLegacy = new FanGeoAggService(Apisauce);
export const getFanGeoAggServiceV1 = () => (fanGeoAggServiceV1 || (fanGeoAggServiceV1 = new FanGeoAggServiceV1()));
export const getEdcm = () => (edcm || (edcm = new EdcmService(getSDKConfig('edcm'))));

export const getPhoneNumberService = () => (phoneNumberService || (phoneNumberService = new PhoneNumberService(getSDKConfig('messaging'))));

export const getSMSService = () => (smsService || (smsService = new Sms(getSDKConfig('messaging'))));
export const getCampaignSDK = () => (campaignSDK || (campaignSDK = new Campaigns(getSDKConfig('messaging'))));
export const getSystemTemplatesSDK = () => (systemTemplatesSDK || (systemTemplatesSDK = new SystemTemplates(getSDKConfig('messaging'))));

export const getCustomTagsSDK = () => (customTagsSDK || (customTagsSDK = new CustomTags(getSDKConfig('fans'))));

export const getProductsSDK = () => (productsSDK || (productsSDK = new Products(getSDKConfig('fans'))));
export const getCelloService = () => (celloService || (celloService = new CelloService()));

export const experienceService = ExperienceFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.ONE_TO_ONE,
);

export const experience1To1Service = ExperienceFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.ONE_TO_ONE,
);
export const experienceLiveClassService =
  ExperienceFactoryService.createService(Apisauce, EXPERIENCE_TYPE.LIVE_CLASS);
export const experienceInteractiveLiveClassService =
  ExperienceFactoryService.createService(
    Apisauce,
    EXPERIENCE_TYPE.INTERACTIVE_LIVE_CLASS,
  );
export const exclusiveContentService = ExperienceFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.EXCLUSIVE_CONTENT,
);

export const courseService = ExperienceFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.COURSE,
);
export const purchasingOptionsService = new PurchasingOptionsService(Apisauce);
export const booking1To1Service = BookingFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.ONE_TO_ONE,
);
export const bookingLiveClassService = BookingFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.LIVE_CLASS,
);
export const bundleService = ExperienceFactoryService.createService(
  Apisauce,
  EXPERIENCE_TYPE.BUNDLE,
);
export const timeRangeService = new TimeRangeService(Apisauce);
export const photoService = new PhotoService(Apisauce);
export const videoService: IVideoService = new VideoService();

export const awsService = AWSService.getInstance();
export const categoryService = new CategoryService(Apisauce);
export const tagService = new TagService(Apisauce);
export const payoutService = new PayoutService(Apisauce);
export const productService = new ProductService(Apisauce);
export const iapService = new IAPService(Apisauce);
export const firebaseService = new FirebaseService();
export const specialRequestService = new SpecialRequestService(Apisauce);
export const availabilityRuleService = new AvailabilityRuleService(Apisauce);

export const analyticsChartService = new AnalyticsChartService(
  AnalyticsApiSauce,
);

export const getAffiliateService = () => (affiliateService || (affiliateService = new AffiliateService()));
export const getDigitalProductService = () => (digitalProductService || (digitalProductService = new DigitalProductService()));
export const getShortVideoService = () => (shortVideoService || (shortVideoService = new ShortVideoService()));
export const getAnalyticsService = () => (analyticsService || (analyticsService = new AnalyticsService()));

export const useGatewayFlag = (routeFlag: FLAGS) => {
  const useApiGateway = isOn(FLAGS.USE_API_GATEWAY)
  const routing = isOn(routeFlag)

  return routing || useApiGateway
}

export function salesService(): SalesServiceInterface {
  const routing = useGatewayFlag(FLAGS.SALES_ROUTING)
  
  return routing ? getSalesServiceV1() : salesServiceLegacy;
}

export function ryeShopifyService(): RyeShopifyService {
  const routing = useGatewayFlag(FLAGS.SHOPIFY_ROUTING);

  return routing ? getRyeShopifyServiceV1() : ryeShopifyServiceLegacy;
}

//api route switcher between legacy
export function talentService(): TalentService {
  const routing = useGatewayFlag(FLAGS.PROFILE_SERVICE_ROUTING);

  return routing ? getTalentServiceV1() : talentServiceLegacy;
}

export function linkRedirectService(): LinkRedirectService {
  const routing = useGatewayFlag(FLAGS.PROFILE_SERVICE_ROUTING);

  return routing
    ? (getLinkRedirectServiceV1() as unknown as LinkRedirectService)
    : linkRedirectServiceLegacy;
}

export const dspService = new DspService(Apisauce);

export function initProfileId(profileId: string) {
  getSalesServiceV1().init(profileId);
  getShopifyServiceV1().init(profileId);
  getTalentServiceV1().init(profileId);
  getLinkRedirectServiceV1().init(profileId);
  getEdcm().init(profileId);
  messagingAdaptor.init(profileId);
  getCampaignSDK().init(profileId);
  getCustomTagsSDK().init(profileId);
  getProductsSDK().init(profileId);
  getFansServiceV1().init(profileId);
  getSegmentServiceV1().init(profileId);
  getFanGeoAggServiceV1().init(profileId);
  getPhoneNumberService().init(profileId);
  videoService.init(profileId);
  getAffiliateService().init(profileId);
  getSMSService().init(profileId);
  getSystemTemplatesSDK().init(profileId);
  getShortVideoService().init(profileId);
  getAnalyticsService().init(profileId);
}

export function profileGetter() {
  const routing = useGatewayFlag(FLAGS.PROFILE_SERVICE_ROUTING);

  return routing ? getTalentServiceV1().getProfile() : authService.getUserProfile();
}

const fans = () => {
  return getFansServiceV1();
};

const segment = () => {
  return getSegmentServiceV1();
};

const fanGeoAgg = () => {
  return getFanGeoAggServiceV1();
};

export const services = {
  fans,
  segment,
  fanGeoAgg,
};
