import React, { useContext } from 'react';
import {
    GlyphButton,
    GridTable,
    Section,
    Tag,
} from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import { get } from 'lodash-es';
import { Link, useParams } from 'react-router-dom';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import { CONTRACT_TERM_TYPES } from 'src/constants';
import { updateNrTerms } from 'src/urls/frontend-royalties';
import type { GetContractQuery } from 'src/apollo/queries/contract/__generated__/get-contract';
import NrContractTermsTableColumns from 'src/components/contract-detail/nr-contract-terms-table-columns';
import RestrictedByAbacusProfileWrapper from 'src/components/restricted-by-abacus-profile-wrapper';
import { getCountryName } from 'src/utils/country';

type AbacusContract = NonNullable<GetContractQuery['abacusContract']>;
type ContractTerms =
    NonNullable<AbacusContract['contractTerms']> extends (infer T)[] ? T : null;
type ContractTermCondition = NonNullable<ContractTerms['conditions']>[0];
type ContractTermSchedules = NonNullable<
    ContractTerms['contractTermSchedules']
>[0];

export interface NrContractTermBlockPropType {
    term: ContractTerms;
}

export const NrContractTermBlock: React.FC<NrContractTermBlockPropType> = ({
    term,
}) => {
    const { contractId } = useParams<{ contractId: string }>();
    const { state } = useContext(ContractTermContext);
    const storeList: string[] = state.stores;
    const transactionTypeList = state.transactionTypes;
    const defaultCriteria = ['All'];

    const getCountries = (countryCodes: string[]) =>
        !countryCodes || !countryCodes.length
            ? defaultCriteria
            : countryCodes.map((code: string) => getCountryName(code));

    const getStores = (storeIds: string[]) =>
        !storeIds || !storeIds.length
            ? defaultCriteria
            : storeIds?.map(
                  (storeId: string) => storeList[parseInt(storeId, 10)]
              );

    const getTransactionTypes = (transactionTypeIds: string[]) =>
        !transactionTypeIds || !transactionTypeIds.length
            ? defaultCriteria
            : transactionTypeIds.map(
                  (transactionTypeId: string) =>
                      transactionTypeList[transactionTypeId] &&
                      transactionTypeList[transactionTypeId].txnTypeCode.concat(
                          ' - ',
                          transactionTypeList[transactionTypeId].txnTypeName
                      )
              );

    const getFormattedConditions = (conditions: Array<ContractTermCondition>) =>
        conditions.map((condition: ContractTermCondition, index: number) => {
            return {
                conditionRowNumber: index + 1,
                termConditionName: condition.contractTermConditionName,
                transactionType: getTransactionTypes(
                    get(condition, 'conditions.transactionTypes', [])
                ),
                service: getStores(get(condition, 'conditions.stores', [])),
                country: getCountries(
                    get(condition, 'conditions.countries', [])
                ),
                commission: condition.commission,
            };
        });

    const renderContractTermSchedules = (
        contractTermSchedules: ContractTermSchedules[] | null
    ) => {
        return contractTermSchedules
            ? contractTermSchedules.map((item, index) => (
                  <span
                      key={index}
                      className="ContractDetail-nr-term-scheduleItem"
                  >
                      {index > 0 && (
                          <span className="ContractDetail-nr-term-scheduleItem-dot">
                              {' '}
                              •{' '}
                          </span>
                      )}
                      {'scheduleName' in item
                          ? `${item.scheduleName} (${
                                item.scheduleAttachments?.totalCount || 0
                            })`
                          : item.name}
                      {'scheduleName' in item && item.conditions?.autoAdd && (
                          <Tag>
                              <span className="AutoAdd-container">
                                  <GlyphIcon name="check" size={12} />
                                  <span className="AutoAdd-text">
                                      Auto add new
                                  </span>
                              </span>
                          </Tag>
                      )}
                  </span>
              ))
            : '';
    };

    const getTermTypeLabel = (termType: string) => {
        switch (termType) {
            case CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE:
                return 'Contributor Only';
            case CONTRACT_TERM_TYPES.CONTRIBUTION_SCHEDULE:
                return 'Contribution Schedule';
            default:
                return '';
        }
    };

    const getTermTypeCount = (totalCount: number, termType: string) => {
        switch (termType) {
            case CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE:
                return `${totalCount} Contributors`;
            case CONTRACT_TERM_TYPES.CONTRIBUTION_SCHEDULE:
                return `${totalCount} Schedules`;
            default:
                return '';
        }
    };

    return (
        <Section expandable defaultExpanded={false} level="sub">
            <div className="d-flex flex-column" style={{ width: '100%' }}>
                <div
                    className="d-flex flex-row align-items-center"
                    style={{ gap: '8px' }}
                >
                    <div
                        className="d-flex flex-row"
                        style={{ marginBottom: '4px' }}
                    >
                        <Tag>{getTermTypeLabel(term.termType)}</Tag>
                    </div>
                    <RestrictedByAbacusProfileWrapper>
                        <Link
                            to={updateNrTerms(contractId, term.contractTermId)}
                            data-testid="ContractDetail-nr-terms-button"
                            className="ml-auto"
                        >
                            <GlyphButton
                                className="ContractDetail-nr-terms-editButton"
                                data-testid="nr-terms-editButton"
                                variant="secondary"
                                name="edit"
                            />
                        </Link>
                    </RestrictedByAbacusProfileWrapper>
                </div>
            </div>
            <div className="d-flex flex-column">
                <div className="d-flex flex-row ContractDetail-nr-term-name">
                    {term.contractTermName} ({term.contractTermId})
                </div>
            </div>
            <br />
            <Section.Header>
                <div
                    className="d-flex flex-column"
                    style={{ gap: '2px', width: '100%' }}
                >
                    <div
                        className="align-items-center ContractTermsConditions-labelInfoBlock-detail-sectionHeader"
                        style={{ gap: '8px' }}
                    >
                        <Section.Title>
                            {term!.contractTermSchedules!.length == 1
                                ? renderContractTermSchedules(
                                      term.contractTermSchedules
                                  )
                                : getTermTypeCount(
                                      term!.contractTermSchedules!.length,
                                      term.termType
                                  )}
                        </Section.Title>
                    </div>
                    {term!.contractTermSchedules!.length > 1 && (
                        <div
                            className="align-items-center suite-text-small"
                            style={{ color: 'var(--text-label)', gap: '4px' }}
                        >
                            {renderContractTermSchedules(
                                term.contractTermSchedules
                            )}
                        </div>
                    )}
                </div>
            </Section.Header>
            <Section.Body>
                <Section.Table>
                    <GridTable
                        bordered
                        className="ContractDetail-nr-term-table"
                        columnDefs={NrContractTermsTableColumns()}
                        data={getFormattedConditions(term.conditions || [])}
                        defaultColumnDefs={{
                            headerTextWrap: 'nowrap',
                        }}
                        rowKey="conditionRowNumber"
                        variant="zebra"
                    />
                </Section.Table>
            </Section.Body>
        </Section>
    );
};
