import { Image, Tooltip, Typography } from 'antd';
import React, { ReactNode } from 'react';
import { FolderOpenOutlined } from '@ant-design/icons';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import {
    GlobalTags,
    Owner,
    GlossaryTerms,
    SearchInsight,
    Container,
    Entity,
    EntityType,
    Domain,
} from '../../types.generated';
import { useEntityRegistry } from '../useEntityRegistry';
import AvatarsGroup from '../shared/avatar/AvatarsGroup';
import TagTermGroup from '../shared/tags/TagTermGroup';
import { ANTD_GRAY } from '../entity/shared/constants';
import NoMarkdownViewer from '../entity/shared/components/styled/StripMarkdownText';
import { getNumberWithOrdinal } from '../entity/shared/utils';
import { useEntityData } from '../entity/shared/EntityContext';

const PreviewContainer = styled.div`
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: center;
`;

const PlatformInfo = styled.div`
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    height: 24px;
`;

const TitleContainer = styled.div`
    margin-bottom: 0px;
    line-height: 30px;
`;

const PreviewImage = styled(Image)`
    max-height: 18px;
    width: auto;
    object-fit: contain;
    margin-right: 8px;
    background-color: transparent;
`;

const EntityTitle = styled(Typography.Text)<{ $titleSizePx?: number }>`
    &&& {
        margin-right 8px;
        font-size: ${(props) => props.$titleSizePx || 16}px;
        font-weight: 600;
        vertical-align: middle;
    }
`;

const PlatformText = styled(Typography.Text)`
    font-size: 12px;
    line-height: 20px;
    font-weight: 700;
    color: ${ANTD_GRAY[7]};
`;

const EntityCountText = styled(Typography.Text)`
    font-size: 12px;
    line-height: 20px;
    font-weight: 400;
    color: ${ANTD_GRAY[7]};
`;

const PlatformDivider = styled.div`
    display: inline-block;
    padding-left: 10px;
    margin-right: 10px;
    border-right: 1px solid ${ANTD_GRAY[4]};
    height: 21px;
    vertical-align: text-top;
`;

const DescriptionContainer = styled.div`
    margin-top: 5px;
    color: ${ANTD_GRAY[7]};
`;

const AvatarContainer = styled.div`
    margin-top: 12px;
    margin-right: 32px;
`;

const TagContainer = styled.div`
    display: inline-block;
    margin-left: 0px;
    margin-top: -2px;
`;

const InsightContainer = styled.div`
    margin-top: 12px;
`;

const InsightsText = styled(Typography.Text)`
    font-size: 12px;
    line-height: 20px;
    font-weight: 600;
    color: ${ANTD_GRAY[7]};
`;

const InsightIconContainer = styled.span`
    margin-right: 4px;
`;

const TypeIcon = styled.span`
    margin-right: 8px;
`;

const ContainerText = styled(Typography.Text)`
    font-size: 12px;
    line-height: 20px;
    font-weight: 400;
    color: ${ANTD_GRAY[9]};
`;

const ContainerIcon = styled(FolderOpenOutlined)`
    &&& {
        font-size: 12px;
        margin-right: 4px;
    }
`;

interface Props {
    name: string;
    logoUrl?: string;
    logoComponent?: JSX.Element;
    url: string;
    description?: string;
    type?: string;
    typeIcon?: JSX.Element;
    platform?: string;
    qualifier?: string | null;
    tags?: GlobalTags;
    owners?: Array<Owner> | null;
    snippet?: React.ReactNode;
    insights?: Array<SearchInsight> | null;
    glossaryTerms?: GlossaryTerms;
    container?: Container;
    domain?: Domain | null;
    entityCount?: number;
    dataTestID?: string;
    titleSizePx?: number;
    onClick?: () => void;
    // this is provided by the impact analysis view. it is used to display
    // how the listed node is connected to the source node
    path?: Entity[];
}

export default function DefaultPreviewCard({
    name,
    logoUrl,
    logoComponent,
    url,
    description,
    type,
    typeIcon,
    platform,
    // TODO(Gabe): support qualifier in the new preview card
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    qualifier,
    tags,
    owners,
    snippet,
    insights,
    glossaryTerms,
    domain,
    container,
    entityCount,
    titleSizePx,
    dataTestID,
    onClick,
    path,
}: Props) {
    // sometimes these lists will be rendered inside an entity container (for example, in the case of impact analysis)
    // in those cases, we may want to enrich the preview w/ context about the container entity
    const { entityData } = useEntityData();
    const entityRegistry = useEntityRegistry();
    const insightViews: Array<ReactNode> = [
        ...(insights?.map((insight) => (
            <>
                <InsightIconContainer>{insight.icon}</InsightIconContainer>
                <InsightsText>{insight.text}</InsightsText>
            </>
        )) || []),
    ];
    if (snippet) {
        insightViews.push(snippet);
    }
    return (
        <PreviewContainer data-testid={dataTestID}>
            <div>
                <TitleContainer>
                    <Link to={url}>
                        <PlatformInfo>
                            {(logoUrl && <PreviewImage preview={false} src={logoUrl} alt={platform || ''} />) ||
                                logoComponent}
                            {platform && <PlatformText>{platform}</PlatformText>}
                            {(logoUrl || logoComponent || platform) && <PlatformDivider />}
                            {typeIcon && <TypeIcon>{typeIcon}</TypeIcon>}
                            <PlatformText>{type}</PlatformText>
                            {container && (
                                <Link to={entityRegistry.getEntityUrl(EntityType.Container, container?.urn)}>
                                    <PlatformDivider />
                                    <ContainerIcon
                                        style={{
                                            color: ANTD_GRAY[9],
                                        }}
                                    />
                                    <ContainerText>
                                        {entityRegistry.getDisplayName(EntityType.Container, container)}
                                    </ContainerText>
                                </Link>
                            )}
                            {entityCount && entityCount > 0 ? (
                                <>
                                    <PlatformDivider />
                                    <EntityCountText>{entityCount.toLocaleString()} entities</EntityCountText>
                                </>
                            ) : null}
                            {path && (
                                <span>
                                    <PlatformDivider />
                                    <Tooltip
                                        title={`This entity is a ${getNumberWithOrdinal(
                                            path?.length + 1,
                                        )} degree connection to ${entityData?.name || 'the source entity'}`}
                                    >
                                        <PlatformText>{getNumberWithOrdinal(path?.length + 1)}</PlatformText>
                                    </Tooltip>
                                </span>
                            )}
                        </PlatformInfo>
                        <EntityTitle onClick={onClick} $titleSizePx={titleSizePx}>
                            {name || ' '}
                        </EntityTitle>
                    </Link>
                    <TagContainer>
                        <TagTermGroup
                            domain={domain}
                            uneditableGlossaryTerms={glossaryTerms}
                            uneditableTags={tags}
                            maxShow={3}
                        />
                    </TagContainer>
                </TitleContainer>
                {description && description.length > 0 && (
                    <DescriptionContainer>
                        <NoMarkdownViewer limit={200}>{description}</NoMarkdownViewer>
                    </DescriptionContainer>
                )}
                {owners && owners.length > 0 && (
                    <AvatarContainer>
                        <AvatarsGroup size={28} owners={owners} entityRegistry={entityRegistry} maxCount={4} />
                    </AvatarContainer>
                )}
                {insightViews.length > 0 && (
                    <InsightContainer>
                        {insightViews.map((insightView, index) => (
                            <span>
                                {insightView}
                                {index < insightViews.length - 1 && <PlatformDivider />}
                            </span>
                        ))}
                    </InsightContainer>
                )}
            </div>
        </PreviewContainer>
    );
}
