import React from 'react';
import { Button, Col, Label, Row } from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { Link } from 'react-router-dom';
import ContractTermCondition from 'src/components/contract-detail/contract-term-condition';
import ContractTermContribution from 'src/components/contract-detail/contract-term-contribution';
import ContractTermLabelName from 'src/components/contract-detail/contract-term-label-name';
import ContractTermProductName from 'src/components/contract-detail/contract-term-product-name';
import ContractTermTrackName from 'src/components/contract-detail/contract-term-track-name';
import RestrictedByAbacusProfileWrapper from 'src/components/restricted-by-abacus-profile-wrapper';
import { CONTRACT_TERM_TYPES, USER_FEATURES } from 'src/constants';
import { updateTerms } from 'src/urls/frontend-royalties';
import { isFeatureFlagEnabled } from 'src/utils/feature-flag';
import type { AbacusContractTerm } from 'src/components/contract-detail/contract-terms-detail-presentational';
import type { AbacusContractTermCondition } from 'src/types/abacus-contract-term';

export interface ContractTermDetailProps {
    contractTerms: AbacusContractTerm[];
}

export default function ContractTermDetail({
    contractTerms,
}: ContractTermDetailProps) {
    const renderContractTermConditions = (
        contractTermConditions: AbacusContractTermCondition[] | null
    ) =>
        (contractTermConditions ?? []).map(termCondition => (
            <ContractTermCondition
                key={termCondition.contractTermConditionId}
                contractTermCondition={termCondition}
            />
        ));

    const editLink = (
        contractId: string,
        contractTermId: string,
        type: string,
        isBaseTerm: boolean
    ) => {
        const defaultValue = '#';
        if (isBaseTerm) return updateTerms(contractId, contractTermId, 'terms');

        if (type === CONTRACT_TERM_TYPES.PRODUCT)
            return updateTerms(contractId, contractTermId, 'product-exception');

        if (type === CONTRACT_TERM_TYPES.TRACK)
            return updateTerms(contractId, contractTermId, 'track-exception');

        return defaultValue;
    };

    const renderCatalogValues = (term: AbacusContractTerm) => {
        if (term.termType === CONTRACT_TERM_TYPES.PRODUCT)
            return term.attachments?.map(productUpc => (
                <ContractTermProductName
                    key={productUpc}
                    productUpc={productUpc}
                />
            ));

        if (term.termType === CONTRACT_TERM_TYPES.TRACK)
            return <ContractTermTrackName isrcs={term?.attachments ?? []} />;

        if (
            term.termType === CONTRACT_TERM_TYPES.CONTRIBUTION &&
            isFeatureFlagEnabled(USER_FEATURES.ABACUS_SHOW_NR_CONTRIBUTIONS)
        )
            return (
                <ContractTermContribution
                    contractTermId={term.contractTermId}
                    count={term.attachments?.length}
                />
            );

        return 'All';
    };

    const renderTermsConditionsTableHeader = (terms: AbacusContractTerm[]) => {
        const showContributors =
            terms[0].termType === CONTRACT_TERM_TYPES.CONTRIBUTION &&
            isFeatureFlagEnabled(USER_FEATURES.ABACUS_SHOW_NR_CONTRIBUTIONS);

        const headers = [
            { name: 'Term Id', size: 1 },
            { name: 'Contributors', size: 1, hide: !showContributors },
            { name: 'Catalog', size: 2 },
            { name: 'Transaction type', size: 2 },
            { name: 'Service', size: 2 },
            { name: 'Country', size: 2 },
            { name: "Label's share", size: 2 },
        ];

        return (
            <Row
                className="ContractTermConditionsTable-header"
                data-testid="ContractTermConditionsTable-header"
            >
                {headers.map(
                    header =>
                        !header.hide && (
                            <Col
                                sm={header.size}
                                key={header.name}
                                className={
                                    showContributors
                                        ? `ContractTermConditionsTable-header-${header.name}`
                                        : ''
                                }
                            >
                                <Label text={header.name} />
                            </Col>
                        )
                )}
            </Row>
        );
    };

    const getTermTypeLabel = (termType: string) => {
        switch (termType) {
            case CONTRACT_TERM_TYPES.PRODUCT:
                return 'Product';
            case CONTRACT_TERM_TYPES.TRACK:
                return 'Track';
            case CONTRACT_TERM_TYPES.CONTRIBUTION:
                return isFeatureFlagEnabled(
                    USER_FEATURES.ABACUS_SHOW_NR_CONTRIBUTIONS
                )
                    ? 'Contribution'
                    : '';
            default:
                return '';
        }
    };

    const renderBaseTermAttachments = (terms: AbacusContractTerm[]) => {
        switch (terms[0].termType) {
            case CONTRACT_TERM_TYPES.LABEL:
                return (
                    <div className="BaseTerm-attachment">
                        {(terms[0]?.attachments ?? []).map(attachment => (
                            <ContractTermLabelName
                                key={attachment}
                                labelId={attachment}
                            />
                        ))}
                    </div>
                );
            case CONTRACT_TERM_TYPES.PRODUCT:
            case CONTRACT_TERM_TYPES.TRACK:
                return (
                    <Col xs="11">
                        <Label text="Label" />
                        <div className="BaseTerm-attachment">
                            {!isEmpty(
                                terms[0].attachmentsRelations?.labelIds
                            ) && (
                                <ContractTermLabelName
                                    key={
                                        terms[0].attachmentsRelations
                                            ?.labelIds?.[0]
                                    }
                                    labelId={
                                        terms[0].attachmentsRelations
                                            ?.labelIds?.[0]
                                    }
                                />
                            )}
                        </div>
                    </Col>
                );
            case CONTRACT_TERM_TYPES.CONTRIBUTION:
            default:
                return '';
        }
    };

    const renderContributors = (term: AbacusContractTerm) => {
        const isContributionType =
            term.termType === CONTRACT_TERM_TYPES.CONTRIBUTION;

        if (
            !isContributionType ||
            !isFeatureFlagEnabled(USER_FEATURES.ABACUS_SHOW_NR_CONTRIBUTIONS)
        )
            return null;

        return (
            <Col
                sm="1"
                className="Contributors"
                data-testid="contributorsTestId"
            >
                {(term.attachmentsRelations?.contributors ?? []).map(c => (
                    <div key={c.id}>
                        {c.name} ({c.id})
                    </div>
                ))}
            </Col>
        );
    };

    const renderBaseTerms = (terms: AbacusContractTerm[]) => {
        const isLabelType = terms[0].termType === CONTRACT_TERM_TYPES.LABEL;
        const isBaseTerm = !isEmpty(terms) && terms[0].isBaseTerm;

        if (!isBaseTerm) return null;

        if (isLabelType)
            return (
                <div>
                    <div data-testid="typeLabelTestId">
                        <Label text={terms[0].termType} />
                    </div>
                    <div className="BaseTerm-attachment">
                        {renderBaseTermAttachments(terms)}
                    </div>
                </div>
            );

        return (
            <Row>
                <Col xs="1">
                    <Label text="Type" />
                    <div
                        className="BaseTerm-attachment"
                        data-testid="typeLabelTestId"
                    >
                        {getTermTypeLabel(terms[0].termType)}
                    </div>
                </Col>
                {renderBaseTermAttachments(terms)}
            </Row>
        );
    };

    const isContributionHideContributions = (term: AbacusContractTerm) =>
        term.termType === CONTRACT_TERM_TYPES.CONTRIBUTION &&
        !isFeatureFlagEnabled(USER_FEATURES.ABACUS_SHOW_NR_CONTRIBUTIONS);

    return (
        <div className="ContractDetail-ContractTerm-detail">
            {renderBaseTerms(contractTerms)}
            {renderTermsConditionsTableHeader(contractTerms)}
            <Row className="ContractTermConditionsTable-body ">
                <Col className="ContractTermConditionsTable-column">
                    {contractTerms.map(term => (
                        <Row
                            className="ContractTermConditionsTable-item"
                            key={`term-condition-${term.contractTermId}`}
                        >
                            <Col sm="1" className="TermConditionIndex">
                                {term.contractTermId}
                            </Col>
                            {renderContributors(term)}
                            <Col sm="2" className="TermConditionCatalog">
                                {renderCatalogValues(term)}
                            </Col>
                            <Col
                                sm={
                                    isContributionHideContributions(term)
                                        ? 9
                                        : 8
                                }
                                className="TermConditionConditions"
                            >
                                {renderContractTermConditions(term.conditions)}
                            </Col>
                            {term.termType !==
                                CONTRACT_TERM_TYPES.CONTRIBUTION && (
                                <RestrictedByAbacusProfileWrapper>
                                    <Col sm="1" data-testid="TermEditButton">
                                        <div>
                                            <Link
                                                to={editLink(
                                                    term.contract.contractId,
                                                    term.contractTermId,
                                                    term.termType,
                                                    term.isBaseTerm
                                                )}
                                            >
                                                <Button variant="quartenary">
                                                    {' '}
                                                    Edit{' '}
                                                </Button>
                                            </Link>
                                        </div>
                                    </Col>
                                </RestrictedByAbacusProfileWrapper>
                            )}
                        </Row>
                    ))}
                </Col>
            </Row>
        </div>
    );
}
