import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import {
    Alert,
    Button,
    GridTable,
    LoadingPageIndicator,
    Pagination,
    useToast,
    Section,
} from '@theorchard/suite-components';
import { Segment } from '@theorchard/suite-frontend';
import { GlyphIcon } from '@theorchard/suite-icons';
import moment from 'moment';
import { OSR_CATEGORY } from 'src/constants';
import { useOsrLazyQuery } from 'src/data/queries';
import { selectOrchardSoundRecording } from 'src/data/queries/orchardSoundRecording/selector';
import {
    AccountCell,
    TrackAudioAttributesCell,
    TrackInactiveReasonCell,
    TrackNameCell,
    TrackRightsAttributesCell,
} from 'src/pages/osrPage/views/overviewView/components/tableCells/tableCells';
import { exportCsv } from 'src/utils/exportCsv';
import { useDisplayRightsAttributesFF } from 'src/utils/features';
import { paginate } from 'src/utils/pagination';
import ActiveTracksSwitch, {
    ActiveTracksSwitchValues,
} from '../../components/activeTracksSwitch/activeTracksSwitch';
import ReferenceTrackModal from './components/referenceTrackModal';
import type { FormattedTrack } from 'src/data/queries/orchardSoundRecording/selector';

export const PARENT_CLASS_NAME = 'OsrPage';
export const CLASS_NAME = `${PARENT_CLASS_NAME}-Views-OverviewView`;

const DEFAULT_PAGE_SIZE = 20;

interface Props {
    tracks: FormattedTrack[];
    id: string;
    handleReload: (shouldReload: boolean) => void;
    handlePolling: (shouldPoll: boolean) => void;
    versionId: string;
}

export interface TableTrack {
    position?: number;
    name: string;
    isrc: string;
    primaryArtists: string;
    featuringArtists: string;
    genre: string;
    accountName: string;
    accountId: number;
    upc: string;
    productId: number;
    productStatus: string;
    releaseDate: string;
    trackId: number;
    duration: string;
    numberOfCountries?: number;
    pLine: string | null;
    ownershipRights: string;
    audioAttributes: string[];
    rightsAttributes: string[];
}

export const formatTracks = (tracks: FormattedTrack[]) => {
    return tracks.map(t => ({
        position: t.position,
        name: t.name,
        isrc: t.isrc,
        primaryArtists: !t.primaryArtists.length
            ? '-'
            : t.primaryArtists.join(','),
        featuringArtists: !t.featuringArtists.length
            ? '-'
            : t.featuringArtists.join(','),
        genre: t.genre,
        accountName: t.accountName,
        accountId: t.accountId,
        upc: t.upc,
        product: t.product,
        productId: t.productId,
        productStatus: t.productStatus,
        releaseDate: moment(t.releaseDate).format('DD MMM YYYY'),
        trackId: t.trackId,
        duration: t.duration,
        numberOfCountries: t.countriesClaimed.length || undefined,
        pLine: t.pLine,
        ownershipRights: t.ownershipRights,
        audioAttributes: t.audioAttributes,
        rightsAttributes: t.rightsAttributes,
        accountType: t.product.label.type,
        subAccountId: t.product.label.id.subaccount || undefined,
        inactiveReason: t.inactiveReason,
        isActive: t.isActive,
    }));
};

const OverviewView: FC<Props> = ({
    tracks,
    id,
    handleReload,
    handlePolling,
    versionId,
}) => {
    useEffect(() => {
        void Segment.trackEvent('View', { category: OSR_CATEGORY }, 'Overview');
    }, []);

    const toast = useToast();
    const [page, setPage] = useState(0);
    const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
    const [open, setOpen] = useState(false);
    const [selectedTrack, setSelectedTrack] = useState<FormattedTrack>();
    const [isRefreshLoading, setIsRefreshLoading] = useState(false);
    const [isRefreshLoadingError, setIsRefreshLoadingError] = useState(false);
    const [isActiveTracksState, setIsActiveTracksState] = useState(true);
    const [executeOsrLazyQuery] = useOsrLazyQuery();
    const isDisplayRightsAttrEnabled = useDisplayRightsAttributesFF();
    const formattedTracks = formatTracks(
        tracks.filter(t => t.isActive === isActiveTracksState)
    );
    const paginatedTracks = paginate(formattedTracks, pageSize);

    const handleExport = () => {
        void Segment.trackEvent(
            'Click',
            { category: OSR_CATEGORY, value: Date.now() },
            'Export Instances'
        );

        const csvRows = formattedTracks?.map(track => ({
            [$t(`orchardSoundRecordings.overviewView.headers.name`)]:
                track.name,
            [$t(`orchardSoundRecordings.overviewView.headers.isrc`)]:
                track.isrc,
            [$t(`orchardSoundRecordings.overviewView.headers.primaryArtists`)]:
                track.primaryArtists,
            [$t(
                `orchardSoundRecordings.overviewView.headers.featuringArtists`
            )]: track.featuringArtists,
            [$t(`orchardSoundRecordings.overviewView.headers.genre`)]:
                track.genre,
            [$t(`orchardSoundRecordings.overviewView.headers.accountName`)]:
                track.accountName,
            [$t(`orchardSoundRecordings.overviewView.headers.accountId`)]:
                track.accountId,
            [$t(`orchardSoundRecordings.overviewView.headers.upc`)]: track.upc,
            [$t(`orchardSoundRecordings.overviewView.headers.productId`)]:
                track.productId,
            [$t(`orchardSoundRecordings.overviewView.headers.productStatus`)]:
                track.productStatus,
            [$t(`orchardSoundRecordings.overviewView.headers.releaseDate`)]:
                track.releaseDate,
            [$t(`orchardSoundRecordings.overviewView.headers.trackId`)]:
                track.trackId,
            [$t(`orchardSoundRecordings.overviewView.headers.duration`)]:
                track.duration,
            [$t(`orchardSoundRecordings.overviewView.headers.pLine`)]:
                track.pLine,
        }));

        const filename = `OSR_${id}_Instances_${new Date().toLocaleDateString()}`;

        exportCsv(csvRows, filename);
    };

    const handleReferenceTrack = (track: TableTrack) => {
        void Segment.trackEvent(
            'Click',
            { category: OSR_CATEGORY, value: Date.now() },
            `Change Reference Track - ${id}`
        );
        const foundTrack = tracks.find(t => t.trackId === track.trackId);
        if (foundTrack) {
            setSelectedTrack(foundTrack);
            setOpen(true);
        }
    };

    const handleReferenceTrackClose = () => {
        void Segment.trackEvent(
            'Click',
            { category: OSR_CATEGORY, value: Date.now() },
            `Change Reference Track Cancel - ${id}`
        );
        setOpen(false);
    };

    const handleReferenceTrackSave = () => {
        setOpen(false);
        setIsRefreshLoading(true);
        handlePolling(true);

        let timeoutId: NodeJS.Timeout | null = null;

        const intervalId = setInterval(() => {
            if (timeoutId === null)
                timeoutId = setTimeout(() => {
                    setIsRefreshLoading(false);
                    setIsRefreshLoadingError(true);
                    clearInterval(intervalId);
                    handleReload(false);
                    handlePolling(false);
                }, 120000);

            executeOsrLazyQuery({ variables: { id } })
                .then(result => {
                    const loadedOsr = selectOrchardSoundRecording(result.data);
                    if (loadedOsr) {
                        const { versionId: loadedVersionId } = loadedOsr;
                        if (loadedVersionId !== versionId) {
                            if (timeoutId) clearTimeout(timeoutId);
                            setIsRefreshLoading(false);
                            clearInterval(intervalId);
                            handleReload(true);
                            handlePolling(false);
                            toast(
                                $t(
                                    `orchardSoundRecordings.overviewView.successRefToast`
                                )
                            );
                        }
                    }
                })
                .catch(() => {
                    if (timeoutId) clearTimeout(timeoutId);
                    clearInterval(intervalId);
                    setIsRefreshLoading(false);
                    setIsRefreshLoadingError(true);
                    handleReload(false);
                    handlePolling(false);
                });
        }, 5000);
    };

    const renderTableHeader = () => (
        <div className={`${CLASS_NAME}-table-header`}>
            <div className={`${CLASS_NAME}-table-header-left`}>
                <div className={`${CLASS_NAME}-table-header-left-pagination`}>
                    <Pagination
                        totalCount={formattedTracks.length}
                        pageSize={pageSize}
                        currentPage={page}
                        onChange={(pageNumber: number) => setPage(pageNumber)}
                        onSetPageSize={(pageNumber: number) =>
                            setPageSize(pageNumber)
                        }
                    />
                </div>
            </div>
            <div className={`${CLASS_NAME}-table-header-right`}>
                <div className={`${CLASS_NAME}-table-header-right-info`}>
                    {isActiveTracksState && (
                        <span>
                            <GlyphIcon name="info" size={12} />
                            {$t(
                                `orchardSoundRecordings.overviewView.tableHeaderInfo`
                            )}
                        </span>
                    )}
                </div>
                {paginatedTracks.length > 0 && (
                    <div className={`${CLASS_NAME}-table-header-right-export`}>
                        <Button
                            variant="quartenary"
                            onClick={handleExport}
                            data-testid="TableExportButton"
                        >
                            {$t(
                                `orchardSoundRecordings.overviewView.exportButton`
                            )}
                        </Button>
                    </div>
                )}
            </div>
        </div>
    );

    const renderRefreshError = () => (
        <div>
            <p className={`${CLASS_NAME}-refresh-error-text`}>
                {$t(
                    `orchardSoundRecordings.overviewView.error.refresh.text.part1`
                )}
                &nbsp;
                <a href="mailto:ContentFingerprintSR@theorchard.com">
                    ContentFingerprintSR@theorchard.com
                </a>
                &nbsp;
                {$t(
                    `orchardSoundRecordings.overviewView.error.refresh.text.part2`
                )}
            </p>
        </div>
    );

    const renderRefreshLoading = () => (
        <Section>
            <div className={`${CLASS_NAME}-reference-track-update-header`}>
                <p className={`${CLASS_NAME}-reference-track-update-text`}>
                    {$t(`orchardSoundRecordings.overviewView.refresh.header`)}
                </p>
                <p className={`${CLASS_NAME}-reference-track-update-text-body`}>
                    {$t(`orchardSoundRecordings.overviewView.refresh.body`)}
                </p>
            </div>
            <Section.Body>
                <LoadingPageIndicator
                    className={`${CLASS_NAME}-loading-refresh-spinner`}
                />
            </Section.Body>
        </Section>
    );

    if (isRefreshLoading) return renderRefreshLoading();

    const handleActiveSwitchChange = (selected: ActiveTracksSwitchValues) => {
        setPage(0);
        setIsActiveTracksState(
            selected === ActiveTracksSwitchValues.ActiveTracks
        );
    };

    return (
        <div className={CLASS_NAME}>
            {isRefreshLoadingError && (
                <div className={`${CLASS_NAME}-ref-track-alert`}>
                    <Alert
                        variant="error"
                        title={$t(
                            `orchardSoundRecordings.overviewView.error.refresh.title`
                        )}
                        text={renderRefreshError()}
                        dismissible
                    />
                </div>
            )}
            <Section>
                <Section.Body>
                    <ActiveTracksSwitch
                        defaultValue={ActiveTracksSwitchValues.ActiveTracks}
                        onChange={handleActiveSwitchChange}
                    />
                    <Section.Table>
                        <GridTable
                            className={`${CLASS_NAME}-table`}
                            variant="zebra"
                            header={renderTableHeader()}
                            data={paginatedTracks[page]}
                            paginated
                            totalCount={formattedTracks.length}
                            page={page}
                            pageSize={pageSize}
                            onPageChange={(pageNumber: number) =>
                                setPage(pageNumber)
                            }
                            onPageSizeChange={(pageNumber: number) =>
                                setPageSize(pageNumber)
                            }
                            rowActions={{
                                expand: {
                                    icon: <GlyphIcon name="expand" size={16} />,
                                    onClick: track =>
                                        handleReferenceTrack(track),
                                },
                            }}
                        >
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-position`}
                                name="position"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.position`
                                )}
                                sortable={false}
                                visibility="visible-locked"
                                fixed
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-name`}
                                name="name"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.name`
                                )}
                                sortable={false}
                                Cell={TrackNameCell}
                                fixed
                                visibility="visible-locked"
                                fixedOffset={28.7}
                            />
                            {!isActiveTracksState && (
                                <GridTable.Column
                                    className={`${CLASS_NAME}-table-column-inactive-reason`}
                                    name="inactiveReason"
                                    title={$t(
                                        `orchardSoundRecordings.overviewView.headers.inactiveReason`
                                    )}
                                    sortable={false}
                                    Cell={TrackInactiveReasonCell}
                                />
                            )}
                            {isDisplayRightsAttrEnabled && (
                                <GridTable.Column
                                    className={`${CLASS_NAME}-table-column-audio-attributes`}
                                    name="audioAttributes"
                                    title={$t(
                                        `orchardSoundRecordings.overviewView.headers.audioAttributes`
                                    )}
                                    sortable={false}
                                    Cell={TrackAudioAttributesCell}
                                />
                            )}
                            {isDisplayRightsAttrEnabled && (
                                <GridTable.Column
                                    className={`${CLASS_NAME}-table-column-rights-attributes`}
                                    name="rightsAttributes"
                                    title={$t(
                                        `orchardSoundRecordings.overviewView.headers.rightsAttributes`
                                    )}
                                    sortable={false}
                                    Cell={TrackRightsAttributesCell}
                                />
                            )}
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-ownership-rights`}
                                name="ownershipRights"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.ownershipRights`
                                )}
                                sortable={false}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-account-name`}
                                name="accountName"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.accountName`
                                )}
                                sortable={false}
                                Cell={AccountCell}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-primary-artist`}
                                name="primaryArtists"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.primaryArtists`
                                )}
                                sortable={false}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-featuring-artist`}
                                name="featuringArtists"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.featuringArtists`
                                )}
                                sortable={false}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-genre`}
                                name="genre"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.genre`
                                )}
                                sortable={false}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-upc`}
                                name="upc"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.upc`
                                )}
                                sortable={false}
                                align="right"
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-product-id`}
                                name="productId"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.productId`
                                )}
                                sortable={false}
                                align="right"
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-product-status`}
                                name="productStatus"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.productStatus`
                                )}
                                sortable={false}
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-product-release-date`}
                                name="releaseDate"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.releaseDate`
                                )}
                                sortable
                                align="right"
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-track-id`}
                                name="trackId"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.trackId`
                                )}
                                sortable={false}
                                align="right"
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-track-duration`}
                                name="duration"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.duration`
                                )}
                                sortable={false}
                                align="right"
                            />
                            <GridTable.Column
                                className={`${CLASS_NAME}-table-column-pline`}
                                name="pLine"
                                title={$t(
                                    `orchardSoundRecordings.overviewView.headers.pLine`
                                )}
                                sortable={false}
                            />
                        </GridTable>
                    </Section.Table>
                </Section.Body>
            </Section>
            {selectedTrack && (
                <ReferenceTrackModal
                    isOpen={open}
                    handleClose={handleReferenceTrackClose}
                    handleSave={handleReferenceTrackSave}
                    selectedTrack={selectedTrack}
                />
            )}
        </div>
    );
};

export default OverviewView;
