import type { FC } from 'react';
import { useMemo, useState } from 'react';
import { TableBody as AriaTableBody } from 'react-aria-components';
import type { SortDescriptor, Selection } from 'react-aria-components';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEllipsisVertical } from '@fortawesome/pro-duotone-svg-icons';

const DotsVertical: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faEllipsisVertical} className={className} />;
import { Badge } from '@/components/base/badges/badges';
import { Button } from '@/components/base/buttons/button';
import { Table } from '@/components/application/table/table';
import { LeadStatusBadge } from '@/components/shared/status-badge';
import { SourceTag } from '@/components/shared/source-tag';
import { AgeIndicator } from '@/components/shared/age-indicator';
import { formatPhone, formatShortDate } from '@/lib/format';
import { cx } from '@/utils/cx';
import type { Lead } from '@/types/entities';

type LeadTableProps = {
    leads: Lead[];
    onSelectionChange: (selectedIds: string[]) => void;
    selectedIds: string[];
    sortField: string;
    sortDirection: 'asc' | 'desc';
    onSort: (field: string) => void;
    onViewActivity?: (lead: Lead) => void;
    visibleColumns?: Set<string>;
};

type TableRow = {
    id: string;
    type: 'lead' | 'dup-sub';
    lead: Lead;
};

const SpamDisplay = ({ score }: { score: number }) => {
    const colorClass =
        score < 30
            ? 'text-success-primary'
            : score < 60
              ? 'text-warning-primary'
              : 'text-error-primary';

    const bgClass = score >= 60 ? 'rounded px-1.5 py-0.5 bg-error-primary' : '';

    return <span className={cx('text-xs font-semibold', colorClass, bgClass)}>{score}%</span>;
};

export const LeadTable = ({
    leads,
    onSelectionChange,
    selectedIds,
    sortField,
    sortDirection,
    onSort,
    onViewActivity,
    visibleColumns,
}: LeadTableProps) => {
    const [expandedDupId, setExpandedDupId] = useState<string | null>(null);

    const selectedKeys: Selection = new Set(selectedIds);

    const handleSelectionChange = (keys: Selection) => {
        if (keys === 'all') {
            // Only select actual lead rows, not dup sub-rows
            onSelectionChange(leads.map((l) => l.id));
        } else {
            // Filter out dup sub-row IDs
            const leadOnlyIds = [...keys].filter((k) => !String(k).endsWith('-dup')) as string[];
            onSelectionChange(leadOnlyIds);
        }
    };

    const sortDescriptor: SortDescriptor = {
        column: sortField,
        direction: sortDirection === 'asc' ? 'ascending' : 'descending',
    };

    const handleSortChange = (descriptor: SortDescriptor) => {
        if (descriptor.column) {
            onSort(String(descriptor.column));
        }
    };

    // Flatten leads + expanded dup sub-rows into a single list
    const tableRows = useMemo<TableRow[]>(() => {
        const rows: TableRow[] = [];
        for (const lead of leads) {
            rows.push({ id: lead.id, type: 'lead', lead });
            if (lead.isDuplicate === true && expandedDupId === lead.id) {
                rows.push({ id: `${lead.id}-dup`, type: 'dup-sub', lead });
            }
        }
        return rows;
    }, [leads, expandedDupId]);

    const allColumns = [
        { id: 'phone', label: 'Phone', allowsSorting: true, defaultWidth: 150 },
        { id: 'name', label: 'Name', allowsSorting: true, defaultWidth: 160 },
        { id: 'email', label: 'Email', allowsSorting: false, defaultWidth: 180 },
        { id: 'campaign', label: 'Campaign', allowsSorting: false, defaultWidth: 140 },
        { id: 'ad', label: 'Ad', allowsSorting: false, defaultWidth: 80 },
        { id: 'source', label: 'Source', allowsSorting: true, defaultWidth: 100 },
        { id: 'firstContactedAt', label: 'First Contact', allowsSorting: true, defaultWidth: 130 },
        { id: 'lastContactedAt', label: 'Last Contact', allowsSorting: true, defaultWidth: 130 },
        { id: 'status', label: 'Status', allowsSorting: true, defaultWidth: 100 },
        { id: 'createdAt', label: 'Age', allowsSorting: true, defaultWidth: 80 },
        { id: 'spamScore', label: 'Spam', allowsSorting: true, defaultWidth: 70 },
        { id: 'dups', label: 'Dups', allowsSorting: false, defaultWidth: 60 },
        { id: 'actions', label: '', allowsSorting: false, defaultWidth: 50 },
    ];

    const columns = visibleColumns
        ? allColumns.filter(c => visibleColumns.has(c.id) || c.id === 'actions')
        : allColumns;

    return (
        <div className="overflow-hidden rounded-xl ring-1 ring-secondary">
            <Table
                aria-label="Leads table"
                selectionMode="multiple"
                selectionBehavior="toggle"
                selectedKeys={selectedKeys}
                onSelectionChange={handleSelectionChange}
                sortDescriptor={sortDescriptor}
                onSortChange={handleSortChange}
                size="sm"
            >
                <Table.Header columns={columns}>
                    {(column) => (
                        <Table.Head
                            key={column.id}
                            id={column.id}
                            label={column.label}
                            allowsSorting={column.allowsSorting}
                            allowsResizing={column.id !== 'actions'}
                            defaultWidth={column.defaultWidth}
                            minWidth={50}
                        />
                    )}
                </Table.Header>

                <AriaTableBody items={tableRows}>
                    {(row) => {
                        const { lead } = row;
                        const firstName = lead.contactName?.firstName ?? '';
                        const lastName = lead.contactName?.lastName ?? '';
                        const name = `${firstName} ${lastName}`.trim() || '\u2014';
                        const phone = lead.contactPhone?.[0]
                            ? formatPhone(lead.contactPhone[0])
                            : '\u2014';
                        const email = lead.contactEmail?.[0]?.address ?? '\u2014';

                        // Render duplicate sub-row
                        if (row.type === 'dup-sub') {
                            return (
                                <Table.Row
                                    key={row.id}
                                    id={row.id}
                                    className="bg-warning-primary"
                                >
                                    <Table.Cell className="pl-10">
                                        <span className="text-xs text-tertiary">{phone}</span>
                                    </Table.Cell>
                                    <Table.Cell>
                                        <span className="text-xs text-tertiary">{name}</span>
                                    </Table.Cell>
                                    <Table.Cell>
                                        <span className="text-xs text-tertiary">{email}</span>
                                    </Table.Cell>
                                    <Table.Cell>
                                        {lead.leadSource ? (
                                            <SourceTag source={lead.leadSource} size="sm" />
                                        ) : (
                                            <span className="text-tertiary">{'\u2014'}</span>
                                        )}
                                    </Table.Cell>
                                    <Table.Cell>
                                        <Badge size="sm" type="pill-color" color="warning">
                                            Same phone number
                                        </Badge>
                                    </Table.Cell>
                                    <Table.Cell>
                                        <span className="text-xs text-tertiary">
                                            {lead.createdAt
                                                ? formatShortDate(lead.createdAt)
                                                : '\u2014'}
                                        </span>
                                    </Table.Cell>
                                    <Table.Cell />
                                    <Table.Cell />
                                    <Table.Cell />
                                    <Table.Cell />
                                    <Table.Cell />
                                    <Table.Cell />
                                    <Table.Cell>
                                        <div className="flex gap-2">
                                            <Button size="sm" color="primary">
                                                Merge
                                            </Button>
                                            <Button size="sm" color="secondary">
                                                Keep Separate
                                            </Button>
                                        </div>
                                    </Table.Cell>
                                </Table.Row>
                            );
                        }

                        // Render normal lead row
                        const isSpamRow = (lead.spamScore ?? 0) >= 60;
                        const isSelected = selectedIds.includes(lead.id);
                        const isDup = lead.isDuplicate === true;
                        const isExpanded = expandedDupId === lead.id;

                        const isCol = (id: string) => !visibleColumns || visibleColumns.has(id);

                        return (
                            <Table.Row
                                key={row.id}
                                id={row.id}
                                className={cx(
                                    isSpamRow && !isSelected && 'bg-warning-primary',
                                    isSelected && 'bg-brand-primary',
                                )}
                            >
                                {isCol('phone') && <Table.Cell>
                                    <span className="font-semibold text-primary">{phone}</span>
                                </Table.Cell>}
                                {isCol('name') && <Table.Cell>
                                    <span className="text-secondary">{name}</span>
                                </Table.Cell>}
                                {isCol('email') && <Table.Cell>
                                    <span className="text-tertiary">{email}</span>
                                </Table.Cell>}
                                {isCol('campaign') && <Table.Cell>
                                    {lead.utmCampaign ? (
                                        <Badge size="sm" type="pill-color" color="purple">
                                            {lead.utmCampaign}
                                        </Badge>
                                    ) : (
                                        <span className="text-tertiary">{'\u2014'}</span>
                                    )}
                                </Table.Cell>}
                                {isCol('ad') && <Table.Cell>
                                    {lead.adId ? (
                                        <Badge size="sm" type="pill-color" color="success">
                                            Ad
                                        </Badge>
                                    ) : (
                                        <span className="text-tertiary">{'\u2014'}</span>
                                    )}
                                </Table.Cell>}
                                {isCol('source') && <Table.Cell>
                                    {lead.leadSource ? (
                                        <SourceTag source={lead.leadSource} />
                                    ) : (
                                        <span className="text-tertiary">{'\u2014'}</span>
                                    )}
                                </Table.Cell>}
                                {isCol('firstContactedAt') && <Table.Cell>
                                    <span className="text-tertiary">
                                        {lead.firstContactedAt
                                            ? formatShortDate(lead.firstContactedAt)
                                            : '\u2014'}
                                    </span>
                                </Table.Cell>}
                                {isCol('lastContactedAt') && <Table.Cell>
                                    <span className="text-tertiary">
                                        {lead.lastContactedAt
                                            ? formatShortDate(lead.lastContactedAt)
                                            : '\u2014'}
                                    </span>
                                </Table.Cell>}
                                {isCol('status') && <Table.Cell>
                                    {lead.leadStatus ? (
                                        <LeadStatusBadge status={lead.leadStatus} />
                                    ) : (
                                        <span className="text-tertiary">{'\u2014'}</span>
                                    )}
                                </Table.Cell>}
                                {isCol('createdAt') && <Table.Cell>
                                    {lead.createdAt ? (
                                        <AgeIndicator dateStr={lead.createdAt} />
                                    ) : (
                                        <span className="text-tertiary">{'\u2014'}</span>
                                    )}
                                </Table.Cell>}
                                {isCol('spamScore') && <Table.Cell>
                                    {lead.spamScore != null ? (
                                        <SpamDisplay score={lead.spamScore} />
                                    ) : (
                                        <span className="text-tertiary">0%</span>
                                    )}
                                </Table.Cell>}
                                {isCol('dups') && <Table.Cell>
                                    {isDup ? (
                                        <button
                                            type="button"
                                            onClick={(e) => {
                                                e.stopPropagation();
                                                setExpandedDupId(isExpanded ? null : lead.id);
                                            }}
                                            className="cursor-pointer border-none bg-transparent text-xs font-semibold text-warning-primary hover:text-warning-primary"
                                        >
                                            1 {isExpanded ? '\u25B4' : '\u25BE'}
                                        </button>
                                    ) : (
                                        <span className="text-tertiary">0</span>
                                    )}
                                </Table.Cell>}
                                <Table.Cell>
                                    <Button
                                        size="sm"
                                        color="tertiary"
                                        iconLeading={DotsVertical}
                                        aria-label="Row actions"
                                        onClick={() => onViewActivity?.(lead)}
                                    />
                                </Table.Cell>
                            </Table.Row>
                        );
                    }}
                </AriaTableBody>
            </Table>
        </div>
    );
};
