import React from 'react';
import { Label } from '@theorchard/suite-components';
import { Page } from '@theorchard/suite-frontend';
import { Link } from 'react-router-dom';
import { SidecarTrigger } from 'src/components/shared/terms-detail';
import 'src/components/shared/terms-detail/styles.scss';
import '../styles.scss';
import { getContractDetail } from 'src/urls/frontend-royalties';
import type { TransferJobProduct } from 'src/apollo/queries/transfer-projects';
import type { SidecarTriggerItem } from 'src/components/shared/terms-detail';

// Shown when a product-level field has no value.
const EMPTY = '-';

// The products sidecar only shows its search filter once the list is long
// enough to be worth filtering.
const PRODUCT_SEARCH_MIN = 10;

const primaryArtistName = (product: TransferJobProduct['product']): string => {
    const artists = (product.primaryArtists ?? []).filter(
        (a): a is NonNullable<typeof a> => a != null
    );
    const primary =
        artists.find(a => a.artistType?.toLowerCase() === 'primary') ??
        artists[0];
    return primary?.artistName ?? EMPTY;
};

// Builds the searchable product list shown in the project's products sidecar.
// The name is the row label; identifying metadata (code, UPC, artist, format)
// is packed into the subtitle so the sidecar's filter can match on any of them.
export const productSidecarItems = (
    products: TransferJobProduct[]
): SidecarTriggerItem[] =>
    products.map(({ product }) => {
        const artist = primaryArtistName(product);
        return {
            label: product.productName ?? `Product ${product.productId}`,
            subtitle: [
                product.productCode,
                product.upc,
                artist === EMPTY ? null : artist,
                product.format,
            ]
                .filter((v): v is string => Boolean(v))
                .join(' • '),
        };
    });

const MetaField: React.FC<{ label: string; value: React.ReactNode }> = ({
    label,
    value,
}) => (
    <Page.Col md={3}>
        <Label text={label} />
        <div>{value}</div>
    </Page.Col>
);

// The project's general information: title, top-level metadata, and a searchable
// sidecar listing the products being transferred (kept out of the page body so a
// project with many products stays readable).
const ProjectTransferCard: React.FC<{
    projectName: string;
    projectId: number;
    // Project-level code. Populated once the federated Project type exposes it
    // (see PORT-164); omitted from the UI until then.
    projectCode?: string | null;
    products: TransferJobProduct[];
    contractId?: string;
    contractName?: string | null;
}> = ({
    projectName,
    projectId,
    projectCode,
    products,
    contractId,
    contractName,
}) => {
    const count = products.length;
    return (
        <div className="ProjectTransferCard">
            <div className="d-flex justify-content-between align-items-center">
                <div className="ProjectTransferCard-title">{projectName}</div>
                <div className="TermsDetail-termHeader-actions">
                    <span className="text-muted">
                        {count} {count === 1 ? 'Product' : 'Products'}
                    </span>
                    <SidecarTrigger
                        id="projectProducts"
                        title="Products to be transferred"
                        heading={`Products (${count})`}
                        items={productSidecarItems(products)}
                        emptyTooltip="No products in this transfer."
                        noMatchText="No products match that search."
                        hideFilter={count < PRODUCT_SEARCH_MIN}
                    />
                </div>
            </div>
            <Page.Grid>
                <MetaField label="Project ID" value={String(projectId)} />
                {projectCode && (
                    <MetaField label="Project Code" value={projectCode} />
                )}
                {contractId && (
                    <MetaField
                        label="Destination Contract"
                        value={
                            <Link to={getContractDetail(contractId)}>
                                {contractName ?? `Contract ${contractId}`}
                            </Link>
                        }
                    />
                )}
            </Page.Grid>
        </div>
    );
};

export default ProjectTransferCard;
