import type { JSX } from 'react';
import React, { useState } from 'react';
import {
    Button,
    ListBox,
    Sidecar,
    Section,
    Tooltip,
} from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import { Link } from 'react-router-dom';
import RestrictedByAbacusProfileWrapper from 'src/components/restricted-by-abacus-profile-wrapper';
import { updateTerms } from 'src/urls/frontend-royalties';
import ContractTermLabelName from './contract-term-label-name';
import type { AttachmentDetail } from './contract-terms-detail-presentational';
import type { ListViewItem } from '@theorchard/suite-components';
import type { ContractTermFormattedPresentational } from 'src/types/contract-term';

export interface ContractTermDetailPresentationalHeaderPropTypes {
    contractTermLabelIndex: number;
    contractTermFormattedDataMapIndex: number;
    termType: string;
    labelId: string;
    contractTermFormattedDataObject: ContractTermFormattedPresentational;
    contractId: string;
    allAttachments: AttachmentDetail[];
}

interface SidecarItem {
    label: string;
    subtitle: string;
}

export const sortSidecarItems = (items: SidecarItem[]): SidecarItem[] => {
    return [...items].sort((a, b) => {
        const labelA = a.label.toLowerCase();
        const labelB = b.label.toLowerCase();

        if (labelA < labelB) return -1;
        if (labelA > labelB) return 1;

        const subtitleA = a.subtitle.toLowerCase();
        const subtitleB = b.subtitle.toLowerCase();

        if (subtitleA < subtitleB) return -1;
        if (subtitleA > subtitleB) return 1;

        return 0;
    });
};

interface MoreOptionsPropTypes {
    hasOptions: boolean;
    // eslint-disable-next-line no-unused-vars
    setIsSidecarOpen: (isOpen: boolean) => void;
}

const MoreOptions = ({
    hasOptions,
    setIsSidecarOpen,
}: MoreOptionsPropTypes): JSX.Element => {
    return (
        <>
            <Button
                className="ContractTermsConditions-labelInfoBlock-detail-sidecarButton"
                data-testid="moreDetailsButton"
                onClick={() => setIsSidecarOpen(true)}
                disabled={!hasOptions}
            >
                <GlyphIcon
                    className="ContractTermsConditions-labelInfoBlock-detail-moreDetails"
                    name="moreDetails"
                    data-testid="moreDetailsGlyphIcon"
                    size={16}
                />
            </Button>
        </>
    );
};

const ContractTermDetailPresentationalHeader: React.FC<
    ContractTermDetailPresentationalHeaderPropTypes
> = ({
    contractTermLabelIndex,
    contractTermFormattedDataMapIndex,
    termType,
    labelId,
    contractTermFormattedDataObject,
    contractId,
    allAttachments,
}) => {
    const [isSidecarOpen, setIsSidecarOpen] = useState(false);
    const closeModal = () => {
        setIsSidecarOpen(false);
    };

    const attachments = contractTermFormattedDataObject.attachments;
    const termName = contractTermFormattedDataObject.contractTermName;
    const sidecarItems = attachments
        ? attachments.map((attachment: string) => {
              const attachmentDetail = allAttachments.find(
                  detailedAttachment => detailedAttachment.value === attachment
              );
              return {
                  label: attachmentDetail?.name ?? '-',
                  subtitle: attachmentDetail?.artistName
                      ? attachment + ' - ' + attachmentDetail.artistName
                      : attachment,
              };
          })
        : [];

    const sortedSidecarItems = sortSidecarItems(sidecarItems);

    const options: ListViewItem[] = sortedSidecarItems.map((item, index) => ({
        ...item,
        value: index.toString(),
    }));

    const hasOptions = options.length > 0;

    const renderSideCar = (termType: string) => {
        const termId = contractTermFormattedDataObject.termId;
        return (
            <>
                {!hasOptions ? (
                    <Tooltip
                        message={`There are no ${termType}s associated with this term.`}
                        id={'noOptionsTooltip'}
                        placement="left"
                    >
                        <MoreOptions
                            hasOptions={hasOptions}
                            setIsSidecarOpen={setIsSidecarOpen}
                        />
                    </Tooltip>
                ) : (
                    <MoreOptions
                        hasOptions={hasOptions}
                        setIsSidecarOpen={setIsSidecarOpen}
                    />
                )}
                <Sidecar
                    className="ContractAttachmentsSidecar"
                    isOpen={isSidecarOpen}
                    onRequestClose={closeModal}
                    title={termName ? termName : termId}
                >
                    <div className="ContractAttachmentsSidecarParent">
                        <h5
                            className="ContractAttachmentsSidecarHeader"
                            data-testid="SidecarHeader"
                        >
                            {termType === 'track' ? 'Tracks' : 'Products'} (
                            {options.length})
                        </h5>
                        <div className="ContractAttachmentsSidecarBody">
                            <ListBox
                                bordered
                                className="ContractAttachmentsListBox"
                                options={options}
                                optionsMatchBy="all"
                                noMatchText={`No ${termType === 'track' ? 'tracks' : 'products'} found for that search input`}
                            />
                        </div>
                    </div>
                </Sidecar>
            </>
        );
    };

    const renderBlockHeaderDetail = (
        labelId: string | undefined | null,
        termType: string,
        catalogLength: number | null | undefined,
        termId: string
    ) => {
        let blockHeaderDetail: React.JSX.Element = <></>;
        const attachmentsAmount = catalogLength ?? 0;
        if (termType != 'label') {
            blockHeaderDetail = (
                <>
                    <ContractTermLabelName
                        dataTestId="ContractTermLabelNamePresentational-testId"
                        className="ContractTermLabelNamePresentational"
                        key={labelId}
                        labelId={labelId}
                    />{' '}
                    &nbsp;•&nbsp; {attachmentsAmount} {termType}s &nbsp;•&nbsp;
                </>
            );
        } else {
            blockHeaderDetail = (
                <>
                    <ContractTermLabelName
                        dataTestId="ContractTermLabelNamePresentational-testId"
                        className="ContractTermLabelNamePresentational"
                        key={labelId}
                        labelId={labelId}
                    />{' '}
                    &nbsp;•&nbsp;
                </>
            );
        }

        return (
            <div
                className="ContractTermsConditions-labelInfoBlock-detail-subHeaderContainer-header mb-3 text-muted"
                data-testid="labelInfoBlock-detail-subHeaderContainer"
            >
                {blockHeaderDetail} {termId}
            </div>
        );
    };

    return (
        <Section.Header>
            <div
                className="d-flex flex-column ContractTermsConditions-labelInfoBlock-detail-header"
                data-testid="labelInfoBlock-detail-header-test"
            >
                <div className="d-flex flex-row align-items-center">
                    <Section.Title testId="ContractPresentationalTermName">
                        {termName ? termName : ''}
                    </Section.Title>
                    <div className="ml-auto ContractTermsConditions-labelInfoBlock-detail-buttons">
                        <RestrictedByAbacusProfileWrapper>
                            <Link
                                className="ContractTermsConditions-labelInfoBlock-detail-edit"
                                data-testid={`termBlockContractEditLink${contractTermFormattedDataMapIndex}${contractTermLabelIndex}`}
                                to={updateTerms(
                                    contractId,
                                    contractTermFormattedDataObject.termId,
                                    termType
                                )}
                            >
                                <GlyphIcon
                                    className="ContractTermsConditions-labelInfoBlock-detail-editIcon"
                                    name="edit"
                                    data-testid="editGlyphIcon"
                                    size={16}
                                />
                            </Link>
                        </RestrictedByAbacusProfileWrapper>
                        {termType !== 'label' && renderSideCar(termType)}
                    </div>
                </div>
                <div className="d-flex flex-row align-items-center suite-text-large">
                    {renderBlockHeaderDetail(
                        labelId,
                        termType,
                        contractTermFormattedDataObject.catalogLength,
                        contractTermFormattedDataObject.termId
                    )}
                </div>
            </div>
        </Section.Header>
    );
};

export default ContractTermDetailPresentationalHeader;
