import { Button, Card, GridTable, Label } from '@theorchard/suite-components';
import { groupBy } from 'lodash';
import React, { useState } from 'react';
import { TIKTOK_KEY } from 'src/components/fingerprintRulesOAPanel/fingerprint-rules-oa-panel';
import { PolicyType } from 'src/types';
import DeliveryRightsModal from './deliveryRightsModal/delivery-rights-modal';
import type { FC } from 'react';
import type {
    AccountFingerprintRules,
    FingerprintRule,
    Territory,
} from 'src/types';

export interface DeliveryRightsProps {
    rules: AccountFingerprintRules;
    territories: Territory[] | undefined;
    onCountryChange: (event: Policy) => void;
}

export const CLASS_NAME = 'DeliveryRights';

export interface Policy {
    service: string;
    type: string;
    endDate: string | undefined;
    nbOfCountries: number;
    countries: string[];
}

const getCurrentRules = (rules: FingerprintRule[]): FingerprintRule[] => {
    return rules.filter(rule => {
        if (
            rule.policy !== PolicyType['carveout'] &&
            rule.active &&
            rule.startDate &&
            new Date(rule.startDate) < new Date()
        ) {
            if (
                rule.endDate &&
                (rule.endDate === '-' || new Date(rule.endDate) > new Date())
            ) {
                return rule;
            }
        }
    });
};

const getCarveoutRules = (rules: FingerprintRule[]): FingerprintRule[] => {
    return rules.filter(
        rule => rule.policy === PolicyType['carveout'] && rule.active
    );
};

const getPolicies = (rules: FingerprintRule[]): Policy[] => {
    const activeRules = rules.filter(r => r.active);
    let groupedRules: any = {};
    const groupedByService = groupBy(activeRules, 'service');
    groupedRules = groupedByService;
    Object.keys(groupedByService).forEach(serviceKey => {
        groupedRules[serviceKey] = groupBy(
            groupedByService[serviceKey],
            'policy'
        );
        Object.keys(groupedRules[serviceKey]).forEach(policyKey => {
            groupedRules[serviceKey][policyKey] = groupBy(
                groupedRules[serviceKey][policyKey],
                'endDate'
            );
        });
    });

    const result: Policy[] = [];
    for (const serviceKey in groupedRules) {
        const serviceValue = groupedRules[serviceKey];
        for (const policyKey in serviceValue) {
            const policyValue = serviceValue[policyKey];
            for (const endDateKey in policyValue) {
                const endDateValue = policyValue[endDateKey];
                const foundStarService = endDateValue.find(
                    (rule: FingerprintRule) => rule.service === '*'
                );
                const foundStarTerritory = endDateValue.find(
                    (rule: FingerprintRule) => rule.territory === '*'
                );
                result.push({
                    service: foundStarService ? 'Global' : serviceKey,
                    type: policyKey,
                    endDate: endDateKey,
                    nbOfCountries: foundStarTerritory
                        ? 249
                        : endDateValue.length,
                    countries: endDateValue.map(
                        (rule: FingerprintRule) => rule.territory
                    ),
                });
            }
        }
    }

    return result;
};

export const DeliveryRights: FC<DeliveryRightsProps> = ({
    rules,
    territories,
    onCountryChange,
}) => {
    const [openVendor, setOpenVendor] = useState(false);
    const [openSubaccount, setOpenSubaccount] = useState(false);
    const closeVendorModal = () => {
        setOpenVendor(false);
    };
    const closeSubaccountModal = () => {
        setOpenSubaccount(false);
    };
    const handleCountryChange = (event: Policy) => {
        onCountryChange(event);
    };

    const { accountType, vendorRules, subaccountRules } = rules;
    const filteredVendorRules = vendorRules.filter(
        r => r.service.toLowerCase() === TIKTOK_KEY
    );
    const filteredSubaccountRules = subaccountRules.filter(
        r => r.service.toLowerCase() === TIKTOK_KEY
    );

    const currentVendorRules = getCurrentRules(filteredVendorRules);
    const currentSubaccountRules = getCurrentRules(filteredSubaccountRules);

    const allCurrentPolicies = getPolicies(
        currentVendorRules.concat(currentSubaccountRules)
    );

    const carveoutVendorRules = getCarveoutRules(filteredVendorRules);
    const carveoutSubaccountRules = getCarveoutRules(filteredSubaccountRules);

    return (
        <div className={`${CLASS_NAME}-rights-body`}>
            <Card className={`${CLASS_NAME}-delivery SuiteCard`}>
                <Card.Header className={`${CLASS_NAME}-delivery-title`}>
                    {$t('fingerprintRules.deliveryRights.delivery.title')}
                </Card.Header>

                <Card.Body className={`${CLASS_NAME}-delivery-body`}>
                    <Card
                        className={`${CLASS_NAME}-delivery-body-contractual SuiteCard`}
                    >
                        <div
                            className={`${CLASS_NAME}-delivery-body-contractual-title`}
                        >
                            {$t(
                                'fingerprintRules.deliveryRights.delivery.contractual.title'
                            )}
                        </div>
                        <div
                            className={`${CLASS_NAME}-delivery-body-contractual-value`}
                        >
                            {$t(
                                'fingerprintRules.deliveryRights.delivery.contractual.value'
                            )}
                        </div>
                    </Card>

                    <Card
                        className={`${CLASS_NAME}-delivery-body-account SuiteCard`}
                    >
                        <div
                            className={`${CLASS_NAME}-delivery-body-account-title`}
                        >
                            {$t(
                                'fingerprintRules.deliveryRights.delivery.account.title'
                            )}
                        </div>
                        {(currentVendorRules.length > 0 ||
                            carveoutVendorRules.length > 0) && (
                            <div
                                className={`${CLASS_NAME}-delivery-body-account-value`}
                            >
                                <Button
                                    variant="quartenary"
                                    size="sm"
                                    onClick={() => setOpenVendor(true)}
                                >
                                    {$t(
                                        'fingerprintRules.deliveryRights.delivery.account.view'
                                    )}
                                </Button>
                                <DeliveryRightsModal
                                    title={$t(
                                        'fingerprintRules.deliveryRights.delivery.modal.accountTitle'
                                    )}
                                    isOpen={openVendor}
                                    onRequestClose={closeVendorModal}
                                    territories={territories}
                                    rules={currentVendorRules}
                                    carveoutRules={carveoutVendorRules}
                                    accountType="Vendor"
                                />
                            </div>
                        )}
                        {currentVendorRules.length === 0 &&
                            carveoutVendorRules.length === 0 && (
                                <div
                                    className={`${CLASS_NAME}-delivery-body-account-no-value`}
                                >
                                    {$t(
                                        'fingerprintRules.deliveryRights.delivery.subaccount.noValue'
                                    )}
                                </div>
                            )}
                    </Card>
                    {accountType === 'Subaccount' && (
                        <div>
                            <hr />
                            <div
                                className={`${CLASS_NAME}-delivery-body-account`}
                            >
                                <Label
                                    text={$t(
                                        'fingerprintRules.deliveryRights.delivery.subaccount.title'
                                    )}
                                />
                                {(currentSubaccountRules.length > 0 ||
                                    carveoutSubaccountRules.length > 0) && (
                                    <div
                                        className={`${CLASS_NAME}-delivery-body-account-value`}
                                    >
                                        <Button
                                            variant="link"
                                            onClick={() =>
                                                setOpenSubaccount(true)
                                            }
                                        >
                                            {$t(
                                                'fingerprintRules.deliveryRights.delivery.account.view'
                                            )}
                                        </Button>
                                        <DeliveryRightsModal
                                            title={$t(
                                                'fingerprintRules.deliveryRights.delivery.modal.subaccountTitle'
                                            )}
                                            isOpen={openSubaccount}
                                            onRequestClose={
                                                closeSubaccountModal
                                            }
                                            territories={territories}
                                            rules={currentSubaccountRules}
                                            carveoutRules={
                                                carveoutSubaccountRules
                                            }
                                            accountType="Subaccount"
                                        />
                                    </div>
                                )}
                                {currentSubaccountRules.length === 0 &&
                                    carveoutSubaccountRules.length === 0 && (
                                        <div
                                            className={`${CLASS_NAME}-delivery-body-account-no-value`}
                                        >
                                            {$t(
                                                'fingerprintRules.deliveryRights.delivery.subaccount.noValue'
                                            )}
                                        </div>
                                    )}
                            </div>
                        </div>
                    )}
                </Card.Body>
            </Card>

            <Card className={`${CLASS_NAME}-policy SuiteCard`}>
                <div className={`${CLASS_NAME}-policy-title`}>
                    <p>{$t('fingerprintRules.deliveryRights.policy.title')}</p>
                </div>
                <div className={`${CLASS_NAME}-policy-table`}>
                    <GridTable
                        variant="zebra"
                        data={allCurrentPolicies}
                        bordered={true}
                        selectable={false}
                        shadowed
                    >
                        <GridTable.Column
                            name="service"
                            title="Service"
                            sortable={false}
                        />
                        <GridTable.Column
                            name="type"
                            title="Rule Type"
                            sortable={false}
                        />
                        <GridTable.Column
                            name="endDate"
                            title="End date"
                            sortable={false}
                            align="right"
                        />
                        <GridTable.Column
                            name="nbOfCountries"
                            title="Country"
                            sortable={false}
                            align="right"
                            Cell={({ data }: { data: Policy }) => {
                                return (
                                    <div
                                        className={`${CLASS_NAME}-policy-table-country-cell`}
                                    >
                                        <Button
                                            className={`${CLASS_NAME}-policy-table-country-cell-btn`}
                                            variant="link"
                                            onClick={() =>
                                                handleCountryChange(data)
                                            }
                                            data-testid="btn-nb-country"
                                        >
                                            <p
                                                className={`${CLASS_NAME}-policy-table-country-cell-btn-value`}
                                            >
                                                {data.nbOfCountries === 249
                                                    ? 'Global'
                                                    : data.nbOfCountries}
                                            </p>
                                        </Button>
                                    </div>
                                );
                            }}
                        />
                    </GridTable>
                </div>
            </Card>
        </div>
    );
};

export default DeliveryRights;
