import type { ElementType } from 'react';
import React, { useState } from 'react';
import {
    LoadingIndicator,
    InfoMessage,
    Alert,
    SkeletonLoader,
    Tag,
    PageHeader,
    Status,
} from '@theorchard/suite-components';
import { Page, Segment } from '@theorchard/suite-frontend';
import { Illustration } from '@theorchard/suite-icons';
import dayjs from 'dayjs';
import { useParams } from 'react-router-dom';
import { OSR_CATEGORY, DATE_TIME_FORMAT, NA_VALUE } from 'src/constants';
import { useOsrQuery, useReferenceTrackImageQuery } from 'src/data/queries';
import { useGetTrackAttributesQuery } from 'src/data/queries/orchardSoundRecording/trackAttributes';
import { useOsrRulesTabFF } from 'src/utils/features';
import DeliveryView from './views/deliveryView';
import OverviewView from './views/overviewView';
import RightsView from './views/rightsView';
import type { OrchardSoundRecordingMetadata } from 'src/data/queries/orchardSoundRecording/selector';

export const CLASS_NAME = 'OsrPage';

interface ParamTypes {
    osrId: string;
}

interface OsrPageViews {
    overview: React.ElementType;
    delivery: React.ElementType;
    rules?: React.ElementType;
}

const renderOsrPageBody = (
    osr: OrchardSoundRecordingMetadata | undefined,
    views: OsrPageViews
) => {
    if (osr) {
        const { tracks } = osr;
        if (!tracks) {
            void Segment.trackEvent(
                'View',
                { category: OSR_CATEGORY },
                'Overview / No Instances'
            );
            return (
                <>
                    <div className={`${CLASS_NAME}-no-version`}>
                        <div className={`${CLASS_NAME}-no-version-icon`}>
                            <Illustration name="noResults" />
                        </div>
                        <div className={`${CLASS_NAME}-no-version-body`}>
                            <p>
                                {$t(
                                    `orchardSoundRecordings.osrPage.noInstances.part1`
                                )}
                                <br />
                                {$t(
                                    `orchardSoundRecordings.osrPage.noInstances.part2`
                                )}
                            </p>
                        </div>
                        <div className={`${CLASS_NAME}-no-version-contact`}>
                            <p>
                                {$t(
                                    `orchardSoundRecordings.osrPage.contact.part1`
                                )}
                                &nbsp;
                                <a href="mailto:product-support@sonymusic-pde.com">
                                    product-support@sonymusic-pde.com
                                </a>
                                &nbsp;
                                {$t(
                                    `orchardSoundRecordings.osrPage.contact.part2`
                                )}
                            </p>
                        </div>
                    </div>
                </>
            );
        }

        return (
            <Page.Body
                views={views as unknown as Record<string, ElementType>}
                props={osr}
            />
        );
    }

    return <div />;
};

const OsrPage = () => {
    const { osrId } = useParams<ParamTypes>();
    const [reloading, setReloading] = useState(false);
    const [polling, setPolling] = useState(false);
    const isRulesTabEnabled = useOsrRulesTabFF();

    const osrResult = useOsrQuery(String(osrId), reloading);
    const tuids = osrResult?.data?.tracks?.map(t => t.trackId.toString()) || [];
    const { data: trackAttributes } = useGetTrackAttributesQuery(
        tuids,
        reloading
    );
    const refTrackImageResult = useReferenceTrackImageQuery(
        String(osrResult.data?.primaryTrack?.trackId),
        osrResult.loading || !osrResult.data?.primaryTrack?.trackId
    );

    const loading = osrResult.loading || refTrackImageResult.loading;
    const error = osrResult.error || refTrackImageResult.error;

    if (error) return <Alert variant="error" text={error.message} />;

    if ((loading && !osrResult.data) || (loading && !refTrackImageResult.data))
        return <LoadingIndicator />;

    if (!osrResult.data)
        return (
            <InfoMessage
                message={$t(`orchardSoundRecordings.osrPage.error.missingData`)}
            />
        );

    const formattedTracks = osrResult.data.tracks?.map(track => {
        const matchingAttr = trackAttributes.find(
            attr => attr.tuid === track.trackId.toString()
        );
        return {
            ...track,
            audioAttributes: matchingAttr ? matchingAttr.audioAttributes : [],
            rightsAttributes: matchingAttr ? matchingAttr.rightsAttributes : [],
        };
    });
    const updatedOsrData = {
        ...osrResult.data,
        tracks: formattedTracks,
    };

    const handleReload = (shouldReload: boolean) => {
        setReloading(shouldReload);
    };

    const handlePolling = (shouldPoll: boolean) => {
        setPolling(shouldPoll);
    };

    osrResult.data.handleReload = handleReload;
    osrResult.data.handlePolling = handlePolling;

    const items = [
        {
            label: $t(`orchardSoundRecordings.osrPage.views.overviewName`),
            key: 'overview',
        },
    ];

    if (isRulesTabEnabled) {
        items.push({
            label: $t(`orchardSoundRecordings.osrPage.views.rulesName`),
            key: 'rules',
        });
    }
    items.push({
        label: $t(`orchardSoundRecordings.osrPage.views.deliveryName`),
        key: 'delivery',
    });
    const views: OsrPageViews = {
        overview: OverviewView,
        delivery: DeliveryView,
    };

    if (isRulesTabEnabled) {
        views.rules = RightsView;
    }

    const { tracks } = osrResult.data;
    const primaryTrackName = !osrResult.data.isActive
        ? osrResult.data.fallbackTrack?.name || NA_VALUE
        : osrResult.data.primaryTrack
        ? osrResult.data.primaryTrack.name
        : NA_VALUE;
    const primaryTrackArtists = !osrResult.data.isActive
        ? osrResult.data.fallbackTrack?.primaryArtists?.join(', ') || NA_VALUE
        : osrResult.data.primaryTrack
        ? osrResult.data.primaryTrack.primaryArtists.join(', ')
        : NA_VALUE;

    const renderHeader = () => {
        if (polling)
            return (
                <Page.Header>
                    <div className={`${CLASS_NAME}-header-reloading`}>
                        <div
                            className={`${CLASS_NAME}-header-body-reloading-1`}
                        >
                            <SkeletonLoader numberOfItems={1} vertical />
                        </div>
                        <div
                            className={`${CLASS_NAME}-header-body-reloading-2`}
                        >
                            <SkeletonLoader numberOfItems={1} vertical />
                        </div>
                    </div>
                </Page.Header>
            );

        return (
            <Page>
                <PageHeader>
                    <PageHeader.Metadata>
                        <Tag variant="category">
                            {$t(
                                `orchardSoundRecordings.osrPage.header.soundRecording`
                            )}
                        </Tag>
                        <small className="mr-auto">
                            <div className={`${CLASS_NAME}-header`}>
                                <p
                                    className={`${CLASS_NAME}-header-top-line`}
                                >{`${$t(
                                    `orchardSoundRecordings.osrPage.header.soundRecordingId`
                                )}:`}</p>
                                <p
                                    className={`${CLASS_NAME}-header-top-line ${CLASS_NAME}-header-top-line-data`}
                                >
                                    {osrResult.data?.id}
                                </p>
                                <div className={`${CLASS_NAME}-header-divider`}>
                                    |
                                </div>
                                <p className={`${CLASS_NAME}-header-top-line`}>
                                    {`${$t(
                                        `orchardSoundRecordings.osrPage.header.soundRecordingIsrc`
                                    )}:`}
                                </p>
                                <p
                                    className={`${CLASS_NAME}-header-top-line ${CLASS_NAME}-header-top-line-data`}
                                >
                                    {osrResult.data?.isrc}
                                </p>
                                <div className={`${CLASS_NAME}-header-divider`}>
                                    |
                                </div>
                                <p className={`${CLASS_NAME}-header-top-line`}>
                                    {`${$t(
                                        `orchardSoundRecordings.osrPage.header.soundRecordingCreationDate`
                                    )}:`}
                                </p>
                                <p
                                    className={`${CLASS_NAME}-header-top-line ${CLASS_NAME}-header-top-line-data`}
                                >
                                    {dayjs(osrResult.data?.creationDate).format(
                                        DATE_TIME_FORMAT
                                    )}
                                </p>
                            </div>
                        </small>
                    </PageHeader.Metadata>
                    <PageHeader.MainContent>
                        <div style={{ gap: 'var(--padding-medium-small)' }}>
                            <PageHeader.Title>
                                {primaryTrackName}
                                {!osrResult.data?.isActive && (
                                    <Status
                                        text={$t(
                                            'orchardSoundRecordings.osrPage.inactive'
                                        )}
                                        filled
                                        variant="error"
                                    />
                                )}
                            </PageHeader.Title>
                            <div>
                                <span style={{ color: 'var(--text-secondary' }}>
                                    {primaryTrackArtists}
                                </span>
                            </div>
                        </div>
                    </PageHeader.MainContent>
                </PageHeader>
                {tracks && tracks.length > 0 && <Page.Nav items={items} />}
            </Page>
        );
    };
    /* eslint-disable max-len */
    return (
        <Page className={CLASS_NAME}>
            {renderHeader()}
            {renderOsrPageBody(updatedOsrData, views)}
        </Page>
    );
    /* eslint-enable max-len */
};

export default OsrPage;
