import BaseData from "./helpers/baseData";
import { IABBREVPIsSearchObj, IACGDetailsReceiveFields, IACGSearchObj, IBrandDetailsReceiveFields, IBrandSearchObj, ICMISearchObj, IDAAAllergenSearchObj, IDAASearchObj, IDDAAllergenSearchObj, IDDDuplicateAlert, IDDWarningLevelAlert, IDHAAllergenSearchObj, IDHDocLevelAlert, IDHSeverityLevelAlert, IDIASearchObj, IDISeverityAlert, IDocLevelAlert, IFullPISearchObj, IMoleculesReceiveFields, IMoleculesSearchFields, IMoleculesSearchObj, IPBSSearchObj, IProductDetailsReceiveFields, IProductPackDetailsReceiveFields, IProductPackSearchObj, IProductSearchObj, ITGAPoisonSchedules, ITGAPregnancyCate, IVirtualItemDetailsReceiveFields, IVirtualItemSearchObj, IVirtualProductDetailsReceiveFields, IVirtualProductGroupsSearchObj, IVirtualProductSearchObj } from "./interfaces/Interfaces";
import ABBREVPI from "./methods/ABBREVPI";
import ActiveCompositionGroups from "./methods/ActiveCompositionGroups";
import Auth from "./methods/Auth";
import Brands from "./methods/Brands";
import CMI from "./methods/CMI";
import Drugs from "./methods/Drugs";
import FullPIs from "./methods/FullPIs";
import Molecules from "./methods/Molecules";
import PBS from "./methods/PBS";
import ProductImage from "./methods/ProductImage";
import ProductPacks from "./methods/ProductPacks";
import Products from "./methods/Products";
import Definitions from "./methods/Definitions";
import VirtualItems from "./methods/VirtualItems";
import VirtualProductGroups from "./methods/VirtualProductGroups";
import VirtualProducts from "./methods/VirtualProducts";
import Disclaimers from "./methods/Disclaimers";

export default class MIMS {

    constructor(clientId: string, clientSecret: string, grantType: string, apiKey: string) {
        BaseData.setClientId(clientId);
        BaseData.setClientSecret(clientSecret);
        BaseData.setGrantType(grantType);
        BaseData.setAPIKey(apiKey);
        this.generateToken();
    }

    async generateToken() {
        const isNeedToGenerateToken = !BaseData.getAccessTokenData()?.accessToken && (BaseData.getAccessTokenData()?.expiresIn < new Date().getTime());
        if (isNeedToGenerateToken) {
            await Auth.generateToken();
        }
    }

    // get current data version
    async getCurrentDataVersion() {
        const dataVersion = await Auth.getCurrentDataVersion();
        return dataVersion;
    }

    // search by brands
    async searchByBrand(searchParams: IBrandSearchObj) {
        await this.generateToken();
        const brands = await Brands.searchBrand(searchParams);
        return brands;
    }

    // get brand details
    async getBrandDetails(brandId: string, searchParams: IBrandDetailsReceiveFields | null = null) {
        await this.generateToken();
        const brandDetails = await Brands.getBrandDetails(brandId, searchParams);
        return brandDetails;
    }

    // get products lists
    async searchByProducts(searchParams: IProductSearchObj) {
        await this.generateToken();
        const products = await Products.searchProducts(searchParams);
        return products;
    }

    // get product details
    async getProductDetails(productId: string, searchParams: IProductDetailsReceiveFields | null = null) {
        await this.generateToken();
        const productDetails = await Products.getProductDetails(productId, searchParams);
        return productDetails;
    }

    // get product packs list
    async searchByProductPack(searchParams: IProductPackSearchObj) {
        await this.generateToken();
        const productPacks = await ProductPacks.searchProducts(searchParams);
        return productPacks;
    }

    // get product pack details
    async getProductPackDetails(productPackId: string, searchParams: IProductPackDetailsReceiveFields | null = null) {
        await this.generateToken();
        const productPackDetails = await ProductPacks.getProductPackDetails(productPackId, searchParams);
        return productPackDetails;
    }

    // get virtual products list
    async searchByVirtualProducts(searchParams: IVirtualProductSearchObj) {
        await this.generateToken();
        const virtualProducts = await VirtualProducts.searchProducts(searchParams);
        return virtualProducts;
    }

    // get virtual product details
    async getVirtualProductDetails(vpId: string, searchParams: IVirtualProductDetailsReceiveFields | null = null) {
        await this.generateToken();
        const productPackDetails = await VirtualProducts.getProductPackDetails(vpId, searchParams);
        return productPackDetails;
    }

    // get virtual item list
    async searchByVirtualItems(searchParams: IVirtualItemSearchObj) {
        await this.generateToken();
        const virtualItems = await VirtualItems.searchVirtualItems(searchParams);
        return virtualItems;
    }

    // get virtual item details
    async getVirtualItemDetails(viId: string, searchParams: IVirtualItemDetailsReceiveFields | null = null) {
        await this.generateToken();
        const virtualItemDetails = await VirtualItems.getVirtualItemDetails(viId, searchParams);
        return virtualItemDetails;
    }

    // get virtual product groups list
    async searchByVirtualProductGroups(searchParams: IVirtualProductGroupsSearchObj) {
        await this.generateToken();
        const virtualProductGroups = await VirtualProductGroups.searchVirtualProductGroups(searchParams);
        return virtualProductGroups;
    }

    // get acgs list
    async searchByACGs(searchParams: IACGSearchObj) {
        await this.generateToken();
        const acgs = await ActiveCompositionGroups.searchACGS(searchParams);
        return acgs;
    }

    // get acg details
    async getACGDetails(acgId: string, searchParams: IACGDetailsReceiveFields | null = null) {
        await this.generateToken();
        const acgDetails = await ActiveCompositionGroups.getACGDetails(acgId, searchParams);
        return acgDetails;
    }


    // get molecules list
    async searchByMolecules(searchParams: IMoleculesSearchObj) {
        await this.generateToken();
        const molecules = await Molecules.searchMolecules(searchParams);
        return molecules;
    }

    // get molecule details
    async getMoleculeDetails(moleculeId: string, searchParams: IMoleculesReceiveFields | null = null) {
        await this.generateToken();
        const moleculeDetails = await Molecules.getMoleculesDetails(moleculeId, searchParams);
        return moleculeDetails;
    }

    // get PBS details
    async getPBSDetails(pbsCode: string, searchParams: IPBSSearchObj | null = null) {
        await this.generateToken();
        const pbsDetails = await PBS.getPBSDetails(pbsCode, searchParams);
        return pbsDetails;
    }

    // get abbreviated product info (ABBREVPI) list
    async searchByABBREVPI(searchParams: IABBREVPIsSearchObj) {
        await this.generateToken();
        const abbrevPIList = await ABBREVPI.searchProducts(searchParams);
        return abbrevPIList;
    }

    // get abbreviated product details (AVVREVPI details)
    async getABBREVPIDetails(abbrevPIId: string) {
        await this.generateToken();
        const abbrevPIDetails = await ABBREVPI.getABBREVPIDetails(abbrevPIId);
        return abbrevPIDetails;
    }

    // get full product information list
    async searchByFullPIs(searchParams: IFullPISearchObj) {
        await this.generateToken();
        const fullPIsList = await FullPIs.searchProducts(searchParams);
        return fullPIsList;
    }

    // get full product information details
    async getFullPIDetails(fullPIId: string) {
        await this.generateToken();
        const fullPIDetails = await FullPIs.fullPIDetails(fullPIId);
        return fullPIDetails;
    }

    // get Consumer Medicines Information (CMI) List
    async searchByCMI(searchParams: ICMISearchObj) {
        await this.generateToken();
        const cmiList = await CMI.searchCMIs(searchParams);
        return cmiList;
    }

    // get Consumer Medicines Information details
    async getCMIDetails(cmiId: string) {
        await this.generateToken();
        const cmiDetails = await CMI.getCMIDetails(cmiId);
        return cmiDetails;
    }

    // get product image data
    async searchByProductImage(imageId: string) {
        await this.generateToken();
        const productImageData = await ProductImage.searchImage(imageId);
        return productImageData;
    }

    // get product image details
    async getProductImageDetails(imageId: string) {
        await this.generateToken();
        const productImageDetails = await ProductImage.getImageDetails(imageId);
        return productImageDetails;
    }

    // search drug iteraction alerts
    async searchDrugInteractionsAlerts(searchParams: IDIASearchObj) {
        await this.generateToken();
        const diaAlerts = await Drugs.searchDrugIteractions(searchParams);
        return diaAlerts;
    }

    // search drug allergy alerts
    async searchDrugAllergyAlerts(searchParam: IDAASearchObj) {
        await this.generateToken();
        const daaAlerts = await Drugs.searchDrugAllergyAlert(searchParam);
        return daaAlerts;
    }

    // get drug allergy classess
    async getDrugAllergyClasses() {
        await this.generateToken();
        const allergyClasses = await Drugs.getAllergyClassesList();
        return allergyClasses;
    }

    // get drug allergy alert against the active ingredients
    async searchDrugAllergyAlearByActiveIngredients(searchBody: IDAAAllergenSearchObj) {
        await this.generateToken();
        const allergyAlerts = await Drugs.searchDrugAllergyAlertsByIngredients(searchBody);
        return allergyAlerts;
    }

    // get drug health alert by ingredients
    async searchDrugHealthAlert(searchBody: IDHAAllergenSearchObj) {
        await this.generateToken();
        const dhaList = await Drugs.searchDrugHealthAlert(searchBody);
        return dhaList;
    }

    // search drug duplicate alert by ingredients
    async searchDrugDuplicateAlert(searchBody: IDDAAllergenSearchObj) {
        await this.generateToken();
        const ddaList = await Drugs.searchDrugDuplicateAlert(searchBody);
        return ddaList;
    }

    // search created brands delta list
    async searchCreatedBrandsDeltaList() {
        await this.generateToken();
        const list = await Drugs.searchCreatedBrandsDeltaList();
        return list;
    }

    // search updated brands delta list
    async searchUpdatedBrandsDeltaList() {
        await this.generateToken();
        const list = await Drugs.searchUpdatedBrandsDeltaList();
        return list;
    }

    // search deleted brands delta list
    async searchDeletedBrandsDeltaList() {
        await this.generateToken();
        const list = await Drugs.searchDeletedBrandsDeltaList();
        return list;
    }

    // search created products delta list
    async searchCreatedProductsDeltaList() {
        await this.generateToken();
        const list = await Products.getCreatedProductsDeltaList();
        return list;
    }

    // search updated products delta list
    async searchUpdatedProductsDeltaList() {
        await this.generateToken();
        const list = await Products.getUpdatedProductsDeltaList();
        return list;
    }

    // search deleted products delta list
    async searchDeletedProductsDeltaList() {
        await this.generateToken();
        const list = await Products.getDeletedProductsDeltaList();
        return list;
    }

    // search created products packs delta list
    async searchCreatedProductPacksDeltaList() {
        await this.generateToken();
        const list = await ProductPacks.getCreatedProductPackDeltaList();
        return list;
    }

    // search updated products packs delta list
    async searchUpdatedProductPacksDeltaList() {
        await this.generateToken();
        const list = await ProductPacks.getUpdatedProductPackDeltaList();
        return list;
    }

    // search deleted products packs delta list
    async searchDeletedProductPacksDeltaList() {
        await this.generateToken();
        const list = await ProductPacks.getDeletedProductPackDeltaList();
        return list;
    }

    // search created virtual products delta list
    async searchCreatedVirtualProductsDeltaList() {
        await this.generateToken();
        const list = await VirtualProducts.getVirtualProductsDeltaList();
        return list;
    }

    // search updated virtual products delta list
    async searchUpdatedVirtualProductsDeltaList() {
        await this.generateToken();
        const list = await VirtualProducts.getUpdatedVirtualProductsDeltaList();
        return list;
    }

    // search deleted virtual products delta list
    async searchDeletedVirtualProductsDeltaList() {
        await this.generateToken();
        const list = await VirtualProducts.getDeletedVirtualProductsDeltaList();
        return list;
    }

    // search created virtual items delta list
    async searchCreatedVirtualItemsDeltaList() {
        await this.generateToken();
        const list = await VirtualItems.getCreatedVirtualItemsDeltaList();
        return list;
    }

    // search updated virtual items delta list
    async searchUpdatedVirtualItemsDeltaList() {
        await this.generateToken();
        const list = await VirtualItems.getUpdatedVirtualItemsDeltaList();
        return list;
    }

    // search deleted virtual items delta list
    async searchDeletedVirtualItemsDeltaList() {
        await this.generateToken();
        const list = await VirtualItems.getDeletedVirtualItemsDeltaList();
        return list;
    }

    // search created ACG delta list
    async searchCreatedACGDeltaList() {
        await this.generateToken();
        const list = await ActiveCompositionGroups.getACGCreatedDeltaList();
        return list;
    }

    // search updated ACG delta list
    async searchUpdatedACGDeltaList() {
        await this.generateToken();
        const list = await ActiveCompositionGroups.getACGUpdatedDeltaList();
        return list;
    }

    // search deleted ACG delta list
    async searchDeletedACGDeltaList() {
        await this.generateToken();
        const list = await ActiveCompositionGroups.getACGDeletedDeltaList();
        return list;
    }

    // search created Molecules delta list
    async searchCreatedMoleculesDeltaList() {
        await this.generateToken();
        const list = await Molecules.getCreatedMoleculesDeltaList();
        return list;
    }

    // search updated Molecules delta list
    async searchUpdatedMoleculesDeltaList() {
        await this.generateToken();
        const list = await Molecules.getUpdatedMoleculesDeltaList();
        return list;
    }

    // search deleted Molecules delta list
    async searchDeletedMoleculesDeltaList() {
        await this.generateToken();
        const list = await Molecules.getDeletedMoleculesDeltaList();
        return list;
    }

    // search TGA Poison schedules
    async searchPoisonSchedules(searchParams: ITGAPoisonSchedules | null) {
        await this.generateToken();
        const list = await Definitions.getPoisonSchedules(searchParams);
        return list;
    }

    // search TGA Pregnancy Categories
    async searchPragencyCategories(searchParams: ITGAPregnancyCate | null) {
        await this.generateToken();
        const list = await Definitions.getPragnancyCategories(searchParams);
        return list;
    }

    // search TGA Sports Drug Categories
    async searchSportsDrugCategories(searchParams: ITGAPregnancyCate | null) {
        await this.generateToken();
        const list = await Definitions.getSportsDrugCategories(searchParams);
        return list;
    }

    // search Drug Interaction Alert Documentation Level
    async searchDIDocLevelAlert(searchParam: IDocLevelAlert| null) {
        await this.generateToken();
        const list = await Definitions.getDIDocLevelAlert(searchParam);
        return list;
    } 

    // search DI Alert Severity Level
    async searchDISeverityLevelAlert(searchParam: IDISeverityAlert | null) {
        await this.generateToken();
        const list = await Definitions.getDISeverityLevel(searchParam);
        return list;
    } 

    // search Drug Health Alert Documentation Level
    async searchDHDocLevelAlert(searchParam: IDHDocLevelAlert | null) {
        await this.generateToken();
        const list = await Definitions.getDHDocumentLevel(searchParam);
        return list;
    }

    // search Drug Health Alert Severity Level
    async searchDHSeverityLevelAlert(searchParam: IDHSeverityLevelAlert | null) {
        await this.generateToken();
        const list = await Definitions.getDHSeverityLevel(searchParam);
        return list;
    }

    // search Drug Duplicate Alert Warning  Level
    async searchDDWarningLevelAlert(searchParam: IDDWarningLevelAlert | null) {
        await this.generateToken();
        const list = await Definitions.getDDWarningLevel(searchParam);
        return list;
    }

    // search drug duplicate alert duplicate types
    async searchDDDuplicateTypesAlert(searchParam: IDDDuplicateAlert | null) {
        await this.generateToken();
        const list = await Definitions.getDDDuplicateLevelAlert(searchParam);
        return list;
    }

    // get Drug Interaction Alert Disclaimer
    async getDIDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDIDisclaimer();
        return list;
    }

    // get Drug Interaction Alert Non-Disclaimer
    async getDINonDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDINonDisclaimer();
        return list;
    }

    // get Drug Allergy Alert Disclaimer
    async getDADisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDADisclaimer();
        return list;
    }

    // get Drug Allergy Alert Non-Disclaimer
    async getDANonDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDANonDisclaimer();
        return list;
    }

    // get Drug Health Alert Disclaimer
    async getDHDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDHDisclaimer();
        return list;
    }

    // get Drug Health Alert Non-Disclaimer
    async getDHNonDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDHNonDisclaimer();
        return list;
    }

    // get Drug Duplicate Alert Disclaimer
    async getDTDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDTDisclaimer();
        return list;
    }

    // get Drug Duplicate Alert Non-Disclaimer
    async getDTNonDisclaimer() {
        await this.generateToken();
        const list = await Disclaimers.getDTNonDisclaimer();
        return list;
    }
}