import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import {
    Alert,
    Card,
    GridTable,
    InfoMessage,
    SegmentedButton,
    Select,
} from '@theorchard/suite-components';
import { Segment } from '@theorchard/suite-frontend';
import { OSR_CATEGORY } from 'src/constants';
import { AckStatus } from 'src/data/globalTypes';
import {
    useDisplayYoutubeFingerprintRulesFF,
    useOsrLegacyDeliveryHistoryFF,
} from 'src/utils/features';
import { paginate } from 'src/utils/pagination';
import LegacyDeliveryView from './legacyDeliveryView';
import {
    ackStatusToLabelMap,
    DateCell,
    DownloadDeliveryFileCell,
    IngestionStatusCell,
    TypeCell,
    UNAVAILABLE_LABEL,
} from './tableCells';
import type { GridTableRowInstance } from '@theorchard/suite-components';
import type {
    FormattedDeliveryHistory,
    FormattedLegacyDeliveryHistory,
} from 'src/data/queries/orchardSoundRecording/selector';

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

const DEFAULT_PAGE_SIZE = 50;

const TIKTOK_SERVICE_OPTION = {
    value: 'tiktok',
    label: 'TikTok',
};

const YOUTUBE_SERVICE_OPTION = {
    value: 'youtube',
    label: 'YouTube',
};

const SERVICE_OPTIONS = [TIKTOK_SERVICE_OPTION, YOUTUBE_SERVICE_OPTION];

const TYPE_OF_DELIVERY_OPTIONS = [
    {
        value: 'metadata_update',
        label: 'Metadata Update',
    },
    {
        value: 'takedown',
        label: 'Takedown',
    },
    {
        value: 'full_delivery',
        label: 'Full Delivery',
    },
];

const INGESTION_STATUS_OPTIONS = [
    {
        value: 'success',
        label: 'Complete',
    },
    {
        value: 'error',
        label: 'Error',
    },
    {
        value: 'awaited',
        label: 'In Progress',
    },
    {
        value: 'missing',
        label: 'Unavailable',
    },
];

type ViewMode = 'current' | 'legacy';

interface Props {
    deliveryHistory: FormattedDeliveryHistory[];
    legacyDeliveryHistory?: FormattedLegacyDeliveryHistory[];
}

interface Filter {
    value: string;
    label: string;
}

const DeliveryView: FC<Props> = ({
    deliveryHistory,
    legacyDeliveryHistory,
}) => {
    const isYoutubeFingerprintRules = useDisplayYoutubeFingerprintRulesFF();
    const isLegacyFF = useOsrLegacyDeliveryHistoryFF();
    const [viewMode, setViewMode] = useState<ViewMode>('current');
    const [page, setPage] = useState(0);
    const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
    const [expandedRows, setExpandedRows] = useState<Record<string, FC>>({});

    const handleRowClick = ({
        key,
        data,
    }: GridTableRowInstance<FormattedDeliveryHistory>) => {
        if (expandedRows[key]) setExpandedRows({});
        else {
            const ackMessage =
                data.ack === AckStatus.ERROR
                    ? data.ackMessage
                    : !data.ack
                    ? UNAVAILABLE_LABEL
                    : ackStatusToLabelMap[data.ack].label;

            if (!ackMessage) return;

            setExpandedRows({
                [key]: () => (
                    <div className={`${CLASS_NAME}-ExpandableAckMessage`}>
                        <div
                            className={`${CLASS_NAME}-ExpandableAckMessage-isrc`}
                        >
                            {data.orchardSoundRecording.isrc}
                        </div>
                        <div
                            className={`${CLASS_NAME}-ExpandableAckMessage-msg`}
                        >
                            {ackMessage}
                        </div>
                    </div>
                ),
            });
        }
    };

    const defaultServiceFilter = isYoutubeFingerprintRules
        ? undefined
        : TIKTOK_SERVICE_OPTION;
    const [serviceFilter, setServiceFilter] = useState<Filter | undefined>(
        defaultServiceFilter
    );

    const [typeOfDeliveryFilter, setTypeOfDeliveryFilter] = useState<
        Filter | undefined
    >();

    const [ingestionStatusFilter, setIngestionStatusFilter] = useState<
        Filter | undefined
    >();

    const [filteredDeliveryHistory, setFilteredDeliveryHistory] = useState<
        typeof deliveryHistory
    >(
        deliveryHistory.filter(
            delivery =>
                !defaultServiceFilter ||
                delivery.service
                    .toLowerCase()
                    .includes(defaultServiceFilter.value)
        )
    );

    const paginatedHistory = paginate(filteredDeliveryHistory, pageSize);

    const handleIngestionStatusFilter = (status: Filter | undefined) => {
        setIngestionStatusFilter(status);
        handleFilteredDeliveryHistory(
            serviceFilter,
            typeOfDeliveryFilter,
            status
        );
    };

    const handleServiceFilter = (service: Filter | undefined) => {
        setServiceFilter(service);
        handleFilteredDeliveryHistory(
            service,
            typeOfDeliveryFilter,
            ingestionStatusFilter
        );
    };

    const handleTypeOfDeliveryFilter = (typeOfDelivery: Filter | undefined) => {
        setTypeOfDeliveryFilter(typeOfDelivery);
        handleFilteredDeliveryHistory(
            serviceFilter,
            typeOfDelivery,
            ingestionStatusFilter
        );
    };

    const handleFilteredDeliveryHistory = (
        service: Filter | undefined,
        typeOfDelivery: Filter | undefined,
        ingestionStatusFilter: Filter | undefined
    ) => {
        setFilteredDeliveryHistory(
            deliveryHistory.filter(delivery => {
                const filteredByService =
                    !service ||
                    delivery.service.toLowerCase().includes(service.value);
                const filteredByTypeOfDelivery =
                    !typeOfDelivery ||
                    delivery.type.toLowerCase().includes(typeOfDelivery.value);
                const filteredByIngestionStatus =
                    !ingestionStatusFilter ||
                    ingestionStatusFilter.value ===
                        (delivery.ack?.toLowerCase() ||
                            AckStatus.MISSING.toLowerCase());
                return (
                    filteredByService &&
                    filteredByTypeOfDelivery &&
                    filteredByIngestionStatus
                );
            })
        );
        setPage(0);
    };

    useEffect(() => {
        Segment.trackEvent(
            'View',
            { category: OSR_CATEGORY },
            'Delivery'
        ).catch(console.error);
    }, []);

    const isLegacyViewShown = viewMode === 'legacy';

    const getRowKey = (row: FormattedDeliveryHistory) =>
        `delivery-${row.creationDate}-${row.service}-${row.type}-${
            row.xmlSignedUrl ?? ''
        }`;

    return (
        <>
            <div className={`${CLASS_NAME}-toolbar`}>
                {!isLegacyViewShown && (
                    <div className={`${CLASS_NAME}-filters`}>
                        {isYoutubeFingerprintRules && (
                            <>
                                <Select
                                    menuWidth={350}
                                    options={SERVICE_OPTIONS}
                                    hideFilter={true}
                                    placeholder="Service"
                                    compact
                                    onChange={handleServiceFilter}
                                />
                                <Select
                                    menuWidth={350}
                                    options={TYPE_OF_DELIVERY_OPTIONS}
                                    hideFilter={true}
                                    placeholder="Type of Delivery"
                                    compact
                                    onChange={handleTypeOfDeliveryFilter}
                                />
                            </>
                        )}

                        <Select
                            menuWidth={200}
                            options={INGESTION_STATUS_OPTIONS}
                            hideFilter={true}
                            placeholder={$t(
                                'orchardSoundRecordings.deliveryView.filters.ingestionStatusFilterPlaceholder'
                            )}
                            compact
                            onChange={handleIngestionStatusFilter}
                        />
                    </div>
                )}
                {isLegacyFF && (
                    <SegmentedButton
                        className={`${CLASS_NAME}-view-toggle`}
                        defaultValue="current"
                        onChange={val => setViewMode(val as ViewMode)}
                        variant="primary"
                    >
                        <SegmentedButton.Text id="current">
                            {$t(
                                'orchardSoundRecordings.deliveryView.legacy.toggle.current'
                            )}
                        </SegmentedButton.Text>
                        <SegmentedButton.Text id="legacy">
                            {$t(
                                'orchardSoundRecordings.deliveryView.legacy.toggle.legacy'
                            )}
                        </SegmentedButton.Text>
                    </SegmentedButton>
                )}
            </div>

            {!isLegacyViewShown && (
                <>
                    {!deliveryHistory || deliveryHistory.length === 0 ? (
                        <Alert
                            variant="error"
                            text="No delivery history events"
                        />
                    ) : (
                        <Card suite className={CLASS_NAME}>
                            <Card.Body>
                                {filteredDeliveryHistory &&
                                    filteredDeliveryHistory.length > 0 && (
                                        <GridTable
                                            className={`${CLASS_NAME}-table`}
                                            data={paginatedHistory[page]}
                                            variant="zebra"
                                            paginated
                                            totalCount={
                                                filteredDeliveryHistory.length
                                            }
                                            page={page}
                                            pageSize={pageSize}
                                            rowKey={getRowKey}
                                            onRowClick={handleRowClick}
                                            onPageChange={(
                                                pageNumber: number
                                            ) => setPage(pageNumber)}
                                            onPageSizeChange={(
                                                pageNumber: number
                                            ) => setPageSize(pageNumber)}
                                            expandedRows={expandedRows}
                                        >
                                            <GridTable.Column
                                                className={`${CLASS_NAME}-table-column-service`}
                                                name="service"
                                                sortable
                                                title={$t(
                                                    `orchardSoundRecordings.deliveryView.headers.service`
                                                )}
                                            />
                                            <GridTable.Column
                                                className={`${CLASS_NAME}-table-column-type`}
                                                Cell={TypeCell}
                                                name="type"
                                                sortable
                                                title={$t(
                                                    `orchardSoundRecordings.deliveryView.headers.type`
                                                )}
                                            />
                                            <GridTable.Column
                                                className={`${CLASS_NAME}-table-column-creation-date`}
                                                Cell={DateCell}
                                                name="creationDate"
                                                sortable
                                                title={$t(
                                                    `orchardSoundRecordings.deliveryView.headers.creationDate`
                                                )}
                                            />
                                            <GridTable.Column
                                                className={`${CLASS_NAME}-table-column-xml-url`}
                                                Cell={DownloadDeliveryFileCell}
                                                name="xmlSignedUrl"
                                                sortable={false}
                                                title={$t(
                                                    `orchardSoundRecordings.deliveryView.headers.xmlSignedUrl`
                                                )}
                                            />
                                            <GridTable.Column
                                                className={`${CLASS_NAME}-table-column-ingestion-status`}
                                                Cell={IngestionStatusCell}
                                                name="ingestionStatus"
                                                maxWidth="100px"
                                                title={$t(
                                                    `orchardSoundRecordings.deliveryView.headers.ingestionStatus`
                                                )}
                                            />
                                        </GridTable>
                                    )}
                                {(!filteredDeliveryHistory ||
                                    filteredDeliveryHistory.length == 0) && (
                                    <InfoMessage
                                        title={$t(
                                            `orchardSoundRecordings.deliveryView.filters.missingData`
                                        )}
                                        description={$t(
                                            `orchardSoundRecordings.deliveryView.filters.reset`
                                        )}
                                        illustration="error"
                                        size="sm"
                                    />
                                )}
                            </Card.Body>
                        </Card>
                    )}
                </>
            )}

            {isLegacyViewShown && (
                <LegacyDeliveryView
                    legacyDeliveryHistory={legacyDeliveryHistory ?? []}
                />
            )}
        </>
    );
};

export default DeliveryView;
