import type { PropsWithChildren } from 'react';
import React from 'react';
import { GlyphButton, Status } from '@theorchard/suite-components';
import { Link } from 'react-router-dom';
import {
    getProjectTransferDetail,
    getAccountDetail,
} from 'src/urls/frontend-royalties';
import IdentityName from 'src/components/shared/identity-name';
import AccountIcon from 'src/components/account-detail/account-icon';
import type {
    ProjectTransferJob,
    ProjectTransferJobStatus,
} from 'src/apollo/queries/transfer-projects';
import type {
    GridTableColumnDefinition,
    StatusProps,
} from '@theorchard/suite-components';
import type { CellProps } from '@theorchard/suite-components/dist/esm/src/components/table/base/types';

export const TRANSFER_STATUS_VARIANT: Record<
    ProjectTransferJobStatus,
    StatusProps['variant']
> = {
    QUEUED: 'warning',
    PROCESSING: 'warning',
    COMPLETED: 'success',
    FAILED: 'error',
    DELETED: 'neutral',
};

export const TRANSFER_STATUS_FILLED: Record<ProjectTransferJobStatus, boolean> =
    {
        // Pending: solid orange. Processing: outline orange.
        QUEUED: true,
        PROCESSING: false,
        COMPLETED: true,
        FAILED: true,
        DELETED: true,
    };

export const TRANSFER_STATUS_LABEL: Record<ProjectTransferJobStatus, string> = {
    QUEUED: 'Pending',
    PROCESSING: 'Processing',
    COMPLETED: 'Transferred',
    FAILED: 'Failed',
    DELETED: 'Deleted',
};

export const TRANSFER_DELETE_DISABLED_REASON: Partial<
    Record<ProjectTransferJobStatus, string>
> = {
    PROCESSING: 'Transfer is in progress and cannot be deleted',
    COMPLETED: 'Completed transfers cannot be deleted',
    FAILED: 'Failed transfers cannot be deleted',
    DELETED: 'Transfer has already been deleted',
};

export interface StatementPeriodInfo {
    statementPeriodId: string;
    statementPeriodName: string;
}

const formatDate = (iso: string | null | undefined) =>
    iso ? new Date(iso).toISOString().slice(0, 10) : '';

export const formatPeriodKey = (iso: string): string => {
    const [year, month] = iso.slice(0, 10).split('-').map(Number);
    // Revenue cutoff is last day of month; effective period is the NEXT month
    return new Date(year, month, 1).toLocaleString('en-US', {
        month: 'long',
        year: 'numeric',
    });
};

export interface VendorInfo {
    name: string;
    accountId: string;
    brandName?: string;
}

interface ResolvedLabel {
    name: string;
    accountId: string | null;
    vendorId: number;
    subaccountId: number | null;
}

const resolveLabel = (
    label: ProjectTransferJob['originLabel'],
    vendorNames: Map<number, VendorInfo>,
    subaccountNames: Map<string, string>
): ResolvedLabel => {
    const info = vendorNames.get(label.vendorId);
    if (!info)
        return {
            name: String(label.vendorId),
            accountId: null,
            vendorId: label.vendorId,
            subaccountId: label.subaccountId ?? null,
        };
    if (label.subaccountId) {
        const subName =
            subaccountNames.get(`${label.vendorId}:${label.subaccountId}`) ??
            String(label.subaccountId);
        return {
            name: subName,
            accountId: info.accountId,
            vendorId: label.vendorId,
            subaccountId: label.subaccountId,
        };
    }
    return {
        name: info.name,
        accountId: info.accountId,
        vendorId: label.vendorId,
        subaccountId: null,
    };
};

const AccountLabelCell: React.FC<{
    resolved: ResolvedLabel;
    brandName?: string;
}> = ({ resolved, brandName }) => (
    <div>
        <div>
            {brandName && <AccountIcon brandName={brandName} />}
            {resolved.accountId ? (
                <Link to={getAccountDetail(resolved.accountId)}>
                    {resolved.name}
                </Link>
            ) : (
                resolved.name
            )}
        </div>
        <div className="TransferList-subtext">ID: {resolved.vendorId}</div>
        {resolved.subaccountId && (
            <div className="TransferList-subtext">
                Subaccount ID: {resolved.subaccountId}
            </div>
        )}
    </div>
);

const TransferListTableColumns = (
    vendorNames: Map<number, VendorInfo>,
    subaccountNames: Map<string, string>,
    statementPeriods: Map<string, StatementPeriodInfo>,
    onDelete: (jobId: string) => void
): GridTableColumnDefinition<ProjectTransferJob>[] => [
    {
        name: 'status',
        title: 'Status',
        sortable: true,
        minWidth: 'min-content',
        maxWidth: '110px',
        Cell: ({
            data: { status },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <Status
                filled={TRANSFER_STATUS_FILLED[status]}
                variant={TRANSFER_STATUS_VARIANT[status]}
                text={TRANSFER_STATUS_LABEL[status]}
            />
        ),
    },
    {
        name: 'projectTransferJobId',
        title: 'Transfer ID',
        sortable: true,
        minWidth: 'min-content',
        maxWidth: '115px',
        Cell: ({
            data: { projectTransferJobId },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <Link to={getProjectTransferDetail(projectTransferJobId)}>
                {projectTransferJobId}
            </Link>
        ),
    },
    {
        name: 'originLabel',
        title: 'From Account',
        sortable: true,
        minWidth: 'min-content',
        maxWidth: '1fr',
        Cell: ({
            data: { originLabel },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <AccountLabelCell
                resolved={resolveLabel(
                    originLabel,
                    vendorNames,
                    subaccountNames
                )}
                brandName={vendorNames.get(originLabel.vendorId)?.brandName}
            />
        ),
    },
    {
        name: 'destinationLabel',
        title: 'To Account',
        sortable: true,
        minWidth: 'min-content',
        maxWidth: '1fr',
        Cell: ({
            data: { destinationLabel },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <AccountLabelCell
                resolved={resolveLabel(
                    destinationLabel,
                    vendorNames,
                    subaccountNames
                )}
                brandName={
                    vendorNames.get(destinationLabel.vendorId)?.brandName
                }
            />
        ),
    },
    {
        name: 'revenueCutoffDate',
        title: 'Effective Statement Period',
        sortable: false,
        minWidth: 'min-content',
        maxWidth: '190px',
        Cell: ({
            data: { revenueCutoffDate },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => {
            if (!revenueCutoffDate) return <></>;
            const periodKey = formatPeriodKey(revenueCutoffDate);
            const period = statementPeriods.get(periodKey);
            return (
                <div>
                    <div>{periodKey}</div>
                    {period && (
                        <div className="TransferList-subtext">
                            {period.statementPeriodId}
                        </div>
                    )}
                </div>
            );
        },
    },
    {
        name: 'createdBy',
        title: 'Created By',
        sortable: false,
        minWidth: 'min-content',
        maxWidth: '140px',
        Cell: ({
            data: { createdBy },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <IdentityName identity={createdBy.id} />
        ),
    },
    {
        name: 'transferCompletedOn',
        title: 'Transferred On',
        sortable: true,
        minWidth: 'min-content',
        maxWidth: '140px',
        Cell: ({
            data: { transferCompletedOn },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => (
            <>{formatDate(transferCompletedOn)}</>
        ),
    },
    {
        name: 'actions',
        title: 'Actions',
        sortable: false,
        minWidth: 'min-content',
        maxWidth: '80px',
        Cell: ({
            data: { projectTransferJobId, status },
        }: PropsWithChildren<CellProps<ProjectTransferJob>>) => {
            const disabledReason = TRANSFER_DELETE_DISABLED_REASON[status];
            return (
                <GlyphButton
                    name="trash"
                    size="sm"
                    variant="danger-secondary"
                    tooltip={disabledReason ?? 'Delete transfer'}
                    disabled={!!disabledReason}
                    onClick={
                        disabledReason
                            ? undefined
                            : () => onDelete(projectTransferJobId)
                    }
                />
            );
        },
    },
];

export default TransferListTableColumns;
