import React, { useState, useEffect } from 'react';
import { map } from 'lodash';
import { Table, Pagination } from '@orchard/frontend-react-components';
import { useApolloClient } from '@apollo/client';
import { formatMessage } from '@orchard/frontend-localization';
import { PRODUCTS_WITH_SPLITS_QUERY } from './queries/products-with-splits';
import { Splits, SplitsVariables } from './queries/__definitions__/Splits';
import CellLoader from '../../components/loaders/table-cell-loader';
import messages from './i18n';

const CLASS_NAME = 'ManageSplitsPage';

type Props = {
    rowsPerPage?: number
};

/* eslint-disable react/no-unused-prop-types */
type RowData = {
    tuid: string,
    projectName: string,
    productName: string,
    trackName: string,
    upc: string,
    isrc: string,
    collaborators: number
};

type PaginationResult = {
    totalPages: number,
    currentPage: number,
    rows: RowData[]
};
/* eslint-enable react/no-unused-prop-types */

const ManageSplitsPage: React.FC<Props> = ({ rowsPerPage = 10 }) => {
    const apolloClient = useApolloClient();
    const [isSplitsDataLoading, setIsSplitsDataLoading] = useState(true);
    const [paginationData, setPaginationData] = useState<PaginationResult>({
        totalPages: 0,
        currentPage: 0,
        rows: []
    });

    const getPaginatedRows = async ({ page = 1 }) => {
        setIsSplitsDataLoading(true);

        const offset = rowsPerPage * (page - 1);
        const { data: splitsData } = await apolloClient.query<Splits, SplitsVariables>({
            query: PRODUCTS_WITH_SPLITS_QUERY,
            variables: { limit: rowsPerPage, offset }
        });

        const products = splitsData?.allProductsSearch?.products || [];
        const rows: RowData[] = [];
        products.forEach((product) => product.tracks.forEach((track) => {
            const collaboratorCount = track.splits.length;
            rows.push({
                tuid: track.tuid,
                projectName: product.project?.projectName || '',
                productName: product.productName || '',
                trackName: track.trackName || '',
                upc: track.upc || '',
                isrc: track.isrc || '',
                collaborators: collaboratorCount
            });
        }));

        const totalCount = splitsData?.allProductsSearch?.totalCount || 0;
        const totalPages = Math.ceil(totalCount / rowsPerPage);

        setPaginationData({ totalPages, currentPage: page, rows });
        setIsSplitsDataLoading(false);
    };

    const renderRows = (rows: RowData[]) => {
        if (isSplitsDataLoading || !paginationData)
            return null;

        return map(rows, ({ tuid, projectName, productName, trackName, upc, isrc, collaborators }: RowData) => (
            <tr key={ tuid }>
                <td>{ projectName }</td>
                <td>{ productName }</td>
                <td>{ upc }</td>
                <td>{ trackName }</td>
                <td>{ isrc }</td>
                <td>{ collaborators }</td>
            </tr>
        ));
    };

    useEffect(() => {
        getPaginatedRows({ page: 1 });
    }, []); // eslint-disable-line react-hooks/exhaustive-deps

    return (
        <div className={ CLASS_NAME }>
            <h2>{ formatMessage(messages.manageSplits) }</h2>
            <Table className={ `${CLASS_NAME}-table` }>
                <thead className={ `${CLASS_NAME}-head` }>
                    <tr>
                        <th>{ formatMessage(messages.projectName) }</th>
                        <th>{ formatMessage(messages.productName) }</th>
                        <th>{ formatMessage(messages.upc) }</th>
                        <th>{ formatMessage(messages.trackName) }</th>
                        <th>{ formatMessage(messages.isrc) }</th>
                        <th>{ formatMessage(messages.collaborators) }</th>
                    </tr>
                </thead>
                { isSplitsDataLoading ? map(Array(rowsPerPage).fill(null), (_, i) => (
                    <tbody>
                        <tr key={ `loader-${i}` }>
                            <td><CellLoader /></td>
                            <td><CellLoader /></td>
                            <td><CellLoader /></td>
                            <td><CellLoader /></td>
                            <td><CellLoader /></td>
                            <td><CellLoader /></td>
                        </tr>
                    </tbody>
                )) : (
                    <tbody>
                        { renderRows(paginationData.rows) }
                    </tbody>
                ) }
            </Table>
            { paginationData.totalPages > 0 && (
                <Pagination
                    data-testid="pagination"
                    onChange={ (page) => getPaginatedRows({ page }) }
                    totalPages={ paginationData.totalPages }
                    currentPage={ paginationData.currentPage }
                    disabled={ isSplitsDataLoading }
                />
            ) }
        </div>
    );
};

export default ManageSplitsPage;
