// Angular Core
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';

// RxJs
import { Subscription, throwError } from 'rxjs';
import { catchError } from "rxjs/operators";

// Services
import { SearchService } from 'src/app/services/search/search.service';
import { SessionService } from 'src/app/services/session/session.service';
import { SuggestiveService } from 'src/app/services/suggestive/suggestive.service';
import { LocalStorageService } from 'src/app/services/localstorage/local-storage.service';
import { UtilitiesService } from 'src/app/services/utilities/utilities.service';

// Interfaces
import { CategoriesDataInterface } from 'src/app/interfaces/user/categories-data-interface';
import { SessionDataInterface } from 'src/app/interfaces/session-data-interface';
import { DynamicSuggestiveInterface, SuggestiveInterface } from 'src/app/interfaces/user/suggestive-interface';
import { TopPurchasedProducts } from 'src/app/interfaces/common-interfaces';

@Component({
  standalone: false,
    selector: 'app-home',
    templateUrl: './home.component.html',
    styleUrls: ['./home.component.scss', './home.component.query.scss']
})
export class HomeComponent implements OnInit, OnDestroy {

    session!: SessionDataInterface['data'];
    isBuyer!: boolean;
    isAdmin!: boolean;
    renderMe!: boolean;
    hasDispensingData: boolean = false;
    constructor(
        private suggestiveService: SuggestiveService,
        private sessionService: SessionService,
        private searchService: SearchService,
        private router: Router,
        private localStorageService: LocalStorageService,
        private utilitiesService: UtilitiesService
    ) { }

    ngOnInit(): void {
        this.session = this.sessionService.getSession();
        this.isBuyer = this.session.is_buyer;
        this.isAdmin = this.session.is_admin;
        const isLoggedInAsBuyer = this.session.logged_in && this.isBuyer;
        const isPreviewNewUser = this.session.is_preview_mode && !this.session.is_pms_registration_initiated;
        /**
         * Determines whether the component/section should be rendered.
         * 1. User must be logged in as a buyer.
         * 2. Then one of the following must be true:
         *    a) User completed registration beyond step 6 and email is confirmed.
         *    b) User is in preview mode and PMS registration is not initiated.
        */
        this.renderMe =  isLoggedInAsBuyer && ((this.session.reg_step > 6 && this.session.is_email_confirmed === 1) || isPreviewNewUser);
        //Clear search term from object
        this.searchService.setSearchTerm('');
        this.suggestiveService.hasDispensingData().subscribe({
            next: (res: any) => {
              this.hasDispensingData = res.data;
            },
            error: (err) => {
              this.suggestiveService.errorCallBack(err);
            },
            complete: () => {
                //init for dashboard sections on load
                this.homeTabs();
            },
        });
    }

    //Set to show the first tab by default
    activeTab: string = '';
    tcCategories: CategoriesDataInterface['data']['categories']['tcMenu'] = [];

    tcCatCodes: string[] = [];

    /**
     * Top Purchased Products Model
     * @type Object
     */
    topPurchasedProducts: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'MY TOP PURCHASED NDC\'s',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false,
        isFromDispensing: false
    };

    /**
     * Top Short Dated NDCs Model
     * @type Object
     */
    fastMovers: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'Fast Mover\'s',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false
    };

    /**
     * Top Wac NDCs Model
     * @type Object
     */
    topOtcs: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'TOP OTCs',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false
    };

    /**
     * Top trending generics NDCs Model
     * @type Object
     */
    topTrendingGenerics: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'TOP TRENDING GENERICS',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false
    };

    /**
     * Top trending brands NDCs Model
     * @type Object
     */
    topTrendingBrands: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'TOP TRENDING BRANDS',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false
    };

    /**
     * Top trending injectables NDCs Model
     * @type Object
     */
    topTrendingInjectablesAndMore: TopPurchasedProducts = {
        data: [],
        shippingOptions: {},
        config: {
            title: 'TOP TRENDING INJECTABLES & MORE',
            minimumRows: 5,
            isempty: false,
            isloading: true,
            btnText: ""
        },
        postRequestSent: false
    };

    catCode: { [key: string]: TopPurchasedProducts } = {};
    tabs: any;


    /**
     * function to determine the top row in suggestive tabs
     * @param {type} $tabName
     * @returns {Boolean}
     */
    topTabRow(tabName: string) {
        if (tabName === 'recommended' || tabName === 'fastMovers' || tabName === 'topOtcs'
            || tabName === 'trendingGenerics' || tabName === 'trendingBrands' || tabName === 'trendingInjectables') {
            return true;
        }
        return false;
    };

    getSuggestiveSubscribe!: Subscription;
    getCategoriesSubscribe!: Subscription;
    recordHistorySubscribe!: Subscription;
    /**
     * Suggestive data for top trending generics
     * @type {type}
     */
    genericsTab() {
        this.router.navigate(
            ['/market/home'],
            { queryParams: { tab: 'trendingGenerics' } }
        );
        this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('top_trending_generic')
            .pipe(
                catchError(() => {
                    return throwError(() => new Error('ups sommething happend'));
                })
            )
            .subscribe({
                next: (res: SuggestiveInterface) => {
                    let suggestive = res;
                    this.topTrendingGenerics.data = suggestive.data["top_trending_generic"].rows.result;
                    this.topTrendingGenerics.shippingOptions = suggestive.data["top_trending_generic"].rows.shippingInfo;
                    if (this.topTrendingGenerics.data.length < 1) {
                        this.topTrendingGenerics.config.isempty = true;
                    }
                    setTimeout(() => {
                        this.topTrendingGenerics.config.isloading = false;
                    },
                    )
                },
                error: (err) => {
                    this.suggestiveService.errorCallBack(err);
                },
                complete: () => { },
            })
        this.topTrendingGenerics.postRequestSent = true;
    }

    /**
     * Navigates to the market home page with the 'recommended' tab selected,
     * then fetches the top recommended products using the suggestive service.
     * 
     * Marks the recommended post request as sent.
     *
     * @returns void
     */
    recommendedTab() {
        this.router.navigate(
            ['/market/home'],
            { queryParams: { tab: 'recommended' } }
        );
        this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('top_products')
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: SuggestiveInterface) => {
                        this.topPurchasedProducts.data = res.data["top_products"].rows.result;
                        this.topPurchasedProducts.shippingOptions = res.data["top_products"].rows.shippingInfo;
                        this.topPurchasedProducts.isFromDispensing = res.data["top_products"].rows.isFromDispensing;
                        if (res.data["top_products"].rows.result.length < 1) {
                            this.topPurchasedProducts.data = [];
                            this.topPurchasedProducts.config.isempty = true;
                        }
                        this.topPurchasedProducts.config.isloading = false;
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })

            this.topPurchasedProducts.postRequestSent = true;
    }

    /**
     * Gets tabs data
     * @returns {undefined}
     */
    homeTabs() {
        this.localStorageService.removeItem('sortTab');
        this.localStorageService.removeItem('sortTabOrder');
        if (this.renderMe) {
            if (this.tcCatCodes.length < 1) {
                this.tcCatCodes = [];
                this.getCategoriesSubscribe = this.searchService.getCategories()
                    .pipe(
                        catchError(() => {
                            return throwError(() => new Error('ups sommething happend'));
                        })
                    )
                    .subscribe({
                        next: (res: CategoriesDataInterface) => {
                            let tcCategories: CategoriesDataInterface['data']['categories']['tcMenu'] = res.data.categories.tcMenu;
                            tcCategories.forEach((value: CategoriesDataInterface['data']['categories']['tcMenu'][0], key: number) => {
                                let catCode = value.catCode
                                this.tcCatCodes.push(catCode);
                                if (value.catName === '') { // added as per hotfix empty dashboard tab
                                    value.catName = 'Other';
                                }
                                var catCodeObject: TopPurchasedProducts = {
                                    data: [],
                                    shippingOptions: {},
                                    config: {
                                        title: value.catName,
                                        minimumRows: 5,
                                        isempty: false,
                                        isloading: true,
                                        btnText: ""
                                    },
                                    postRequestSent: false
                                };
                                value.catCodeObj = catCodeObject;
                                this.tcCategories.push(value);
                                this.catCode[value.catCode] = catCodeObject;
                            });

                            if (location.search) {
                                var str = location.search;
                                var hashName = str.replace(/\?tab\=/g, '');
                                this.activeTab = hashName;
                                this.clickTab(hashName, '');
                            }
                            else {

                                if (this.hasDispensingData) {
                                    this.activeTab = 'recommended';
                                    this.recommendedTab();
                                } else {
                                    this.activeTab = 'trendingGenerics';
                                    this.genericsTab();
                                }

                            }
                        },
                        error: (err) => {
                            this.searchService.errorCallBack(err);
                        },
                        complete: () => { },
                    })
            }
        }
    };

    /**
     * clickTab funtion for Suggestive data for tab other than trending Generics
     */
    clickTab($tabName: string, params: string = '') {
        if (!this.isAdmin) {
            this.recordTabClicks($tabName);
        }
        this.router.navigate(
            ['/market/home'],
            { queryParams: { tab: $tabName } }
        );
        if ($tabName === 'fastMovers' && !this.fastMovers.postRequestSent) {
            /**
             * Get suggestvive top short dated ndcs on load
             */

            this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('fast_movers')
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: SuggestiveInterface) => {
                        this.fastMovers.data = res.data["fast_movers"].rows.result;
                        this.fastMovers.shippingOptions = res.data["fast_movers"].rows.shippingInfo;
                        if (this.fastMovers.data.length < 1) {
                            this.fastMovers.config.isempty = true;
                        }
                        this.fastMovers.config.isloading = false;
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })
            this.fastMovers.postRequestSent = true;
        }
        else if ($tabName === 'topOtcs' && !this.topOtcs.postRequestSent) {
            /**
             * Suggestive data for top trending wac spreads
             * @type {type}
             */

            this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('top_trending_ndc')
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: SuggestiveInterface) => {
                        this.topOtcs.data = res.data["top_trending_ndc"].rows.result;
                        this.topOtcs.shippingOptions = res.data["top_trending_ndc"].rows.shippingInfo;
                        if (this.topOtcs.data.length < 1) {
                            this.topOtcs.config.isempty = true;
                        }
                        this.topOtcs.config.isloading = false;
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })
            this.topOtcs.postRequestSent = true;
        }
        else if ($tabName === 'trendingBrands' && !this.topTrendingBrands.postRequestSent) {
            /**
             * Suggestive data for top trending brands
             * @type {type}
             */
            this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('top_trending_brand')
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: SuggestiveInterface) => {
                        this.topTrendingBrands.data = res.data["top_trending_brand"].rows.result;
                        this.topTrendingBrands.shippingOptions = res.data["top_trending_brand"].rows.shippingInfo;
                        if (this.topTrendingBrands.data.length < 1) {
                            this.topTrendingBrands.config.isempty = true;
                        }
                        this.topTrendingBrands.config.isloading = false;
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })
            this.topTrendingBrands.postRequestSent = true;
        }
        else if ($tabName === 'trendingInjectables' && !this.topTrendingInjectablesAndMore.postRequestSent) {
            /**
             * Suggestive data for top trending injectables
             * @type {type}
             */
            this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive('injectable_ndc')
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: SuggestiveInterface) => {
                        this.topTrendingInjectablesAndMore.data = res.data["injectable_ndc"].rows.result;
                        this.topTrendingInjectablesAndMore.shippingOptions = res.data["injectable_ndc"].rows.shippingInfo;
                        if (this.topTrendingInjectablesAndMore.data.length < 1) {
                            this.topTrendingInjectablesAndMore.config.isempty = true;
                        }
                        this.topTrendingInjectablesAndMore.config.isloading = false;
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })
            this.topTrendingInjectablesAndMore.postRequestSent = true;
        }
        /**
         * Suggestive data for top trending generics
         * @type {type}
         */
        else if ($tabName === 'trendingGenerics' && !this.topTrendingGenerics.postRequestSent) {
            this.genericsTab();
        }
        /**
         * Suggestive data for top purchased (recommended) products
         * @type {type}
         */
        else if ($tabName === 'recommended' && !this.topPurchasedProducts.postRequestSent) {
            this.recommendedTab();
        }
        else if (this.tcCatCodes.indexOf($tabName) !== -1 && !this.catCode[$tabName].postRequestSent) {
            /**
             * Suggestive data for Therapeutic Group Category Product Info
             * @type {type}
             */

            this.getSuggestiveSubscribe = this.suggestiveService.getSuggestive($tabName)
                .pipe(
                    catchError(() => {
                        return throwError(() => new Error('ups sommething happend'));
                    })
                )
                .subscribe({
                    next: (res: DynamicSuggestiveInterface) => {
                        this.catCode[$tabName].config.isloading = false;
                        this.catCode[$tabName].data = res.data[$tabName].rows.search_result.other[0];
                        this.catCode[$tabName].shippingOptions = res.data[$tabName].rows.search_result.shippingInfo;
                        if (this.catCode[$tabName].data.length < 1) {
                            this.catCode[$tabName].config.isempty = true;
                        }
                    },
                    error: (err) => {
                        this.suggestiveService.errorCallBack(err);
                    },
                    complete: () => { },
                })
            this.catCode[$tabName].postRequestSent = true;
        }
    };

    setActiveTab(catCode: string) {
        this.activeTab = catCode;
    };
    
    /**
     * Records a tab click event for analytics/history tracking.
     *
     * @param tabName
    */
    recordTabClicks(tabName: string) {
        this.recordHistorySubscribe = this.utilitiesService.recordTabClicks(tabName)
            .subscribe({
                error: (err) => {
                    this.utilitiesService.errorCallBack(err);
                }
        })
    };

    ngOnDestroy() {
        this.getSuggestiveSubscribe?.unsubscribe();
        this.getCategoriesSubscribe?.unsubscribe();
        this.recordHistorySubscribe?.unsubscribe();
    }

}
