import { Fragment, useEffect, useState, type ReactNode } from 'react';
import { useDispatch } from 'react-redux';
import Link from 'next/link';
import { Dialog, Transition } from '@headlessui/react';
import 'mantine-datatable/styles.css';
import { DataTable } from '@/components/Shared/DataTable';
import { setPageTitle } from '../../../store/themeConfigSlice';

type ViewTab = 'active' | 'removed' | 'converted' | 'statistics';
type MatchFilter = 'all' | 'full' | 'partial';

type WishlistItem = {
    product_id: string;
    product_title: string;
    product_sku: string;
    product_url: string;
    added_at: string;
    added_at_estimated: boolean;
    removed_at?: string | null;
    converted_at?: string | null;
    status: 'active' | 'removed' | 'converted';
    view_count: number;
    duration_ms: number;
    moved_to_cart_at: string | null;
};

type WishlistConversion = {
    order_id: string;
    converted_at: string;
    match_type: 'full' | 'partial' | 'none';
    path: string;
    matched_items?: { product_title?: string; product_sku?: string }[];
    unmatched_items?: { product_title?: string; product_sku?: string }[];
};

type WishlistOwner = {
    id: string;
    visitor_id: string;
    user: { id: string; name: string; email: string; phone: string } | null;
    active_count: number;
    converted_count: number;
    item_count: number;
    items: WishlistItem[];
    conversions: WishlistConversion[];
};

type WishlistStats = {
    owners: number;
    active_items: number;
    converted_items: number;
    partial_checkouts: number;
    full_checkouts: number;
    top_products: {
        product_title: string;
        product_sku: string;
        added: number;
        converted: number;
    }[];
    converters: {
        visitor_id: string;
        name: string;
        email: string;
        order_id: string;
        match_type: string;
        matched: number;
        unmatched: number;
        converted_at: string;
        path: string;
    }[];
};

const PAGE_SIZES = [5, 10, 20, 30, 50, 100];

function formatDateTime(value?: string | null) {
    if (!value) return '-';
    const date = new Date(value);
    return `${date.toLocaleDateString('id-ID')} ${date.toLocaleTimeString('id-ID')}`;
}

function formatDuration(ms: number) {
    const minutes = Math.max(0, Math.floor((Number(ms) || 0) / 60000));
    if (minutes < 60) return `${minutes} menit`;
    const hours = Math.floor(minutes / 60);
    if (hours < 48) return `${hours} jam`;
    return `${Math.floor(hours / 24)} hari`;
}

function itemTitle(item: { product_title?: string; product_sku?: string; product_id?: string }) {
    return item.product_title || item.product_sku || item.product_id || 'Produk';
}

function visibleItems(record: WishlistOwner, tab: ViewTab) {
    if (tab === 'removed') return record.items.filter((item) => item.status === 'removed');
    if (tab === 'converted') return record.items.filter((item) => item.status === 'converted');
    return record.items.filter((item) => item.status === 'active');
}

function renderStacked(
    items: WishlistItem[],
    render: (item: WishlistItem) => ReactNode
) {
    if (!items.length) return <span className="text-xs text-gray-500">-</span>;
    return (
        <div className="flex flex-col">
            {items.map((item, index) => (
                <div key={`${item.product_id || item.product_sku || index}`} className="flex h-14 items-start py-1 text-xs leading-4">
                    {render(item)}
                </div>
            ))}
        </div>
    );
}

function statusBadge(record: WishlistOwner, tab: ViewTab, matchType: MatchFilter) {
    if (tab === 'removed') return <span className="badge bg-gray-500">Removed</span>;
    if (tab !== 'converted') {
        return <span className="badge bg-warning">Active ({record.active_count})</span>;
    }
    const conversions = (record.conversions || []).filter(
        (entry) => matchType === 'all' || entry.match_type === matchType
    );
    if (!conversions.length) return <span className="badge bg-secondary">Converted</span>;
    return (
        <>
            {conversions.map((entry) =>
                entry.match_type === 'partial' ? (
                    <span key={`${entry.order_id}-partial`} className="badge bg-info mr-1">
                        Partial ({entry.matched_items?.length || 0}/
                        {(entry.matched_items?.length || 0) + (entry.unmatched_items?.length || 0)})
                    </span>
                ) : (
                    <span key={`${entry.order_id}-full`} className="badge bg-success mr-1">
                        Full convert
                    </span>
                )
            )}
        </>
    );
}

function csvEscape(value: string) {
    return `"${String(value || '').replace(/"/g, '""')}"`;
}

function sessionHref(visitorId?: string) {
    const id = String(visitorId || '').trim();
    if (!id) return '/analytics/user-journey?section=sessions';
    return `/analytics/user-journey?section=sessions&visitor_id=${encodeURIComponent(id)}`;
}

const WishlistNotification = () => {
    const dispatch = useDispatch();
    const [isMounted, setIsMounted] = useState(false);
    const [activeTab, setActiveTab] = useState<ViewTab>('active');
    const [matchType, setMatchType] = useState<MatchFilter>('all');
    const [page, setPage] = useState(1);
    const [pageSize, setPageSize] = useState(PAGE_SIZES[0]);
    const [search, setSearch] = useState('');
    const [searchInput, setSearchInput] = useState('');
    const [records, setRecords] = useState<WishlistOwner[]>([]);
    const [totalRecords, setTotalRecords] = useState(0);
    const [stats, setStats] = useState<WishlistStats | null>(null);
    const [isLoading, setIsLoading] = useState(true);
    const [isLoadingDownload, setIsLoadingDownload] = useState(false);
    const [detail, setDetail] = useState<WishlistOwner | null>(null);

    useEffect(() => {
        dispatch(setPageTitle('Wishlist'));
    }, [dispatch]);

    useEffect(() => {
        setIsMounted(true);
    }, []);

    useEffect(() => {
        const load = async () => {
            setIsLoading(true);
            try {
                const api = process.env.API_URL;
                if (activeTab === 'statistics') {
                    const response = await fetch(`${api}api/wishlist/stats`, { credentials: 'include' });
                    const data = await response.json();
                    setStats(response.ok ? data : null);
                    return;
                }
                const params = new URLSearchParams({
                    page: String(page),
                    per_page: String(pageSize),
                    q: search,
                    status: activeTab,
                });
                if (activeTab === 'converted' && matchType !== 'all') {
                    params.set('match_type', matchType);
                }
                const response = await fetch(`${api}api/wishlist/list?${params}`, { credentials: 'include' });
                const data = await response.json();
                setRecords(response.ok ? data.data || [] : []);
                setTotalRecords(response.ok ? data.totalData || 0 : 0);
            } catch {
                setRecords([]);
                setStats(null);
            } finally {
                setIsLoading(false);
            }
        };
        load();
    }, [activeTab, page, pageSize, search, matchType]);

    const handleTabChange = (tab: ViewTab) => {
        setActiveTab(tab);
        setPage(1);
    };

    const downloadCsv = async () => {
        if (activeTab === 'statistics') return;
        setIsLoadingDownload(true);
        try {
            const api = process.env.API_URL;
            const rows: WishlistOwner[] = [];
            let nextPage = 1;
            let total = 0;
            do {
                const params = new URLSearchParams({
                    page: String(nextPage),
                    per_page: '100',
                    q: search,
                    status: activeTab,
                });
                if (activeTab === 'converted' && matchType !== 'all') {
                    params.set('match_type', matchType);
                }
                const response = await fetch(`${api}api/wishlist/list?${params}`, { credentials: 'include' });
                const data = await response.json();
                if (!response.ok) break;
                rows.push(...(data.data || []));
                total = data.totalData || 0;
                nextPage += 1;
            } while (rows.length < total);

            const header = ['name', 'email', 'phone', 'visitor_id', 'items', 'status', 'orders'];
            const lines = rows.map((row) => {
                const items = visibleItems(row, activeTab)
                    .map((item) => `${itemTitle(item)} (${item.product_sku || '-'})`)
                    .join('; ');
                const orders = (row.conversions || []).map((entry) => entry.order_id).filter(Boolean).join('; ');
                return [
                    row.user?.name || row.visitor_id,
                    row.user?.email || '',
                    row.user?.phone || '',
                    row.visitor_id,
                    items,
                    activeTab,
                    orders,
                ].map(csvEscape).join(',');
            });
            const blob = new Blob([[header.join(','), ...lines].join('\n')], { type: 'text/csv;charset=utf-8' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = `wishlist-${activeTab}.csv`;
            link.click();
            URL.revokeObjectURL(url);
        } finally {
            setIsLoadingDownload(false);
        }
    };

    const isStatisticsView = activeTab === 'statistics';

    return (
        <>
            {isMounted && (
                <>
                    <div className="mb-3">
                        <ul className="flex space-x-2 rtl:space-x-reverse">
                            <li>
                                <span>Wishlist</span>
                            </li>
                        </ul>
                    </div>

                    <div className="mb-4 flex flex-wrap gap-2">
                        <button type="button" className={`btn btn-sm ${activeTab === 'active' ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => handleTabChange('active')}>
                            Active
                        </button>
                        <button type="button" className={`btn btn-sm ${activeTab === 'removed' ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => handleTabChange('removed')}>
                            Removed
                        </button>
                        <button type="button" className={`btn btn-sm ${activeTab === 'converted' ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => handleTabChange('converted')}>
                            Converted
                        </button>
                        <button type="button" className={`btn btn-sm ${activeTab === 'statistics' ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => handleTabChange('statistics')}>
                            Statistik
                        </button>
                    </div>

                    {activeTab === 'converted' && (
                        <div className="mb-4 flex flex-wrap gap-2">
                            <button type="button" className={`btn btn-sm ${matchType === 'all' ? 'btn-secondary' : 'btn-outline-secondary'}`} onClick={() => { setMatchType('all'); setPage(1); }}>
                                Semua
                            </button>
                            <button type="button" className={`btn btn-sm ${matchType === 'full' ? 'btn-success' : 'btn-outline-success'}`} onClick={() => { setMatchType('full'); setPage(1); }}>
                                Checkout penuh
                            </button>
                            <button type="button" className={`btn btn-sm ${matchType === 'partial' ? 'btn-info' : 'btn-outline-info'}`} onClick={() => { setMatchType('partial'); setPage(1); }}>
                                Checkout sebagian
                            </button>
                        </div>
                    )}

                    <div className="flex w-full flex-col justify-between gap-4 sm:w-auto sm:flex-row sm:items-center sm:gap-3">
                        {!isStatisticsView && (
                            <>
                                <input
                                    type="text"
                                    className="form-input w-full sm:w-64"
                                    placeholder="Search by name, email, or phone"
                                    value={searchInput}
                                    onChange={(event) => setSearchInput(event.target.value)}
                                    onKeyDown={(event) => {
                                        if (event.key === 'Enter') {
                                            setPage(1);
                                            setSearch(searchInput);
                                        }
                                    }}
                                />
                                <button type="button" className="btn btn-sm btn-outline-success flex items-center justify-center" onClick={downloadCsv} disabled={isLoading || isLoadingDownload}>
                                    {isLoadingDownload ? 'Downloading..' : 'Download Wishlist'}
                                </button>
                            </>
                        )}
                    </div>

                    <div className="panel mt-5 overflow-hidden border-0 px-0 pt-0">
                        <div className="user-table">
                            <div className="datatables pagination-padding">
                                {isLoading ? (
                                    <div className="flex justify-center py-4 text-center">
                                        <span className="ms-3">Please wait, we&apos;re still working to load the data...</span>
                                    </div>
                                ) : isStatisticsView ? (
                                    stats ? (
                                        <div className="space-y-5 p-5">
                                            <div className="grid gap-4 sm:grid-cols-4">
                                                <div className="rounded border border-white-light p-4 dark:border-[#1b2e4b]">
                                                    <div className="text-white-dark">User</div>
                                                    <div className="text-2xl font-semibold">{stats.owners || 0}</div>
                                                </div>
                                                <div className="rounded border border-white-light p-4 dark:border-[#1b2e4b]">
                                                    <div className="text-white-dark">Active Wishlist</div>
                                                    <div className="text-2xl font-semibold">{stats.active_items || 0}</div>
                                                </div>
                                                <div className="rounded border border-white-light p-4 dark:border-[#1b2e4b]">
                                                    <div className="text-white-dark">Partial Checkout</div>
                                                    <div className="text-2xl font-semibold">{stats.full_checkouts || 0}</div>
                                                </div>
                                                <div className="rounded border border-white-light p-4 dark:border-[#1b2e4b]">
                                                    <div className="text-white-dark">Full Checkout</div>
                                                    <div className="text-2xl font-semibold">{stats.partial_checkouts || 0}</div>
                                                </div>
                                            </div>
                                            <div>
                                                <h6 className="mb-3 font-semibold">Most frequently added products to wishlist</h6>
                                                <div className="table-responsive">
                                                    <table className="table-hover">
                                                        <thead>
                                                            <tr>
                                                                <th>Product</th>
                                                                <th>Added</th>
                                                                <th>Checkout</th>
                                                            </tr>
                                                        </thead>
                                                        <tbody>
                                                            {(stats.top_products || []).map((product) => (
                                                                <tr key={`${product.product_sku}-${product.product_title}`}>
                                                                    <td>
                                                                        {product.product_title}
                                                                        <div className="text-xs text-white-dark">{product.product_sku}</div>
                                                                    </td>
                                                                    <td>{product.added}</td>
                                                                    <td>{product.converted}</td>
                                                                </tr>
                                                            ))}
                                                        </tbody>
                                                    </table>
                                                </div>
                                            </div>
                                            <div>
                                                <h6 className="mb-3 font-semibold">Users who checked out from wishlist</h6>
                                                <div className="table-responsive">
                                                    <table className="table-hover">
                                                        <thead>
                                                            <tr>
                                                                <th>User</th>
                                                                <th>Order</th>
                                                                <th>Result</th>
                                                                <th>Path</th>
                                                            </tr>
                                                        </thead>
                                                        <tbody>
                                                            {(stats.converters || []).map((row) => (
                                                                <tr key={`${row.order_id}-${row.visitor_id}`}>
                                                                    <td>
                                                                        {row.name || row.visitor_id}
                                                                        <div className="text-xs text-white-dark">{row.email}</div>
                                                                    </td>
                                                                    <td>
                                                                        {row.order_id ? (
                                                                            <Link href={`/orders/edit/${row.order_id}`} className="text-xs underline">
                                                                                #{row.order_id}
                                                                            </Link>
                                                                        ) : (
                                                                            '-'
                                                                        )}
                                                                    </td>
                                                                    <td>
                                                                        {row.match_type === 'partial' ? 'Partial' : 'Full'} · {row.matched} bought, {row.unmatched} remaining
                                                                    </td>
                                                                    <td>{row.path || '-'}</td>
                                                                </tr>
                                                            ))}
                                                        </tbody>
                                                    </table>
                                                </div>
                                            </div>
                                        </div>
                                    ) : (
                                        <div className="flex justify-center py-4 text-center">
                                            <span className="ms-3">No statistics data</span>
                                        </div>
                                    )
                                ) : (
                                    <DataTable
                                        className="table-hover"
                                        records={records}
                                        idAccessor="id"
                                        minHeight={250}
                                        noRecordsText="No data found"
                                        columns={[
                                            {
                                                accessor: 'name',
                                                title: 'Name',
                                                render: (record) => (
                                                    <div className="font-semibold">{record.user?.name || record.visitor_id}</div>
                                                ),
                                            },
                                            {
                                                accessor: 'email',
                                                title: 'Email',
                                                render: (record) => <>{record.user?.email || '-'}</>,
                                            },
                                            {
                                                accessor: 'phone',
                                                title: 'Phone',
                                                render: (record) => <>{record.user?.phone || '-'}</>,
                                            },
                                            {
                                                accessor: 'items',
                                                title: 'Nama',
                                                width: 280,
                                                cellsClassName: 'align-top whitespace-normal',
                                                render: (record) =>
                                                    renderStacked(visibleItems(record, activeTab), (item) => (
                                                        <div className="max-w-xs">
                                                            <div className="line-clamp-2 whitespace-normal">{itemTitle(item)}</div>
                                                            {item.product_sku ? <div className="text-gray-500">{item.product_sku}</div> : null}
                                                        </div>
                                                    )),
                                            },
                                            {
                                                accessor: 'view_count',
                                                title: 'Dilihat',
                                                width: 90,
                                                cellsClassName: 'align-top',
                                                render: (record) =>
                                                    renderStacked(visibleItems(record, activeTab), (item) => item.view_count),
                                            },
                                            {
                                                accessor: 'duration',
                                                title: 'Durasi',
                                                width: 110,
                                                cellsClassName: 'align-top',
                                                render: (record) =>
                                                    renderStacked(visibleItems(record, activeTab), (item) => formatDuration(item.duration_ms)),
                                            },
                                            {
                                                accessor: 'status',
                                                title: 'Status',
                                                render: (record) => statusBadge(record, activeTab, matchType),
                                            },
                                            {
                                                accessor: 'order',
                                                title: 'Order',
                                                render: (record) => {
                                                    const orders = (record.conversions || []).filter((entry: WishlistConversion) => entry.order_id);
                                                    if (!orders.length) return '-';
                                                    return (
                                                        <div className="flex flex-col gap-1">
                                                            {orders.map((entry: WishlistConversion) => (
                                                                <Link key={entry.order_id} href={`/orders/edit/${entry.order_id}`} className="text-xs underline">
                                                                    #{entry.order_id}
                                                                </Link>
                                                            ))}
                                                        </div>
                                                    );
                                                },
                                            },
                                            {
                                                accessor: 'action',
                                                title: 'Actions',
                                                render: (record) => (
                                                    <div className="flex gap-1">
                                                        <button type="button" className="btn btn-sm btn-outline-info" onClick={() => setDetail(record)}>
                                                            Detail
                                                        </button>
                                                        <Link href={sessionHref(record.visitor_id)} className="btn btn-sm btn-outline-primary">
                                                            Sesi
                                                        </Link>
                                                        {record.user ? (
                                                            <Link href="/notification/abandoned-cart" className="btn btn-sm btn-outline-secondary">
                                                                Cart
                                                            </Link>
                                                        ) : null}
                                                    </div>
                                                ),
                                            },
                                        ]}
                                        highlightOnHover
                                        totalRecords={totalRecords}
                                        recordsPerPage={pageSize}
                                        page={page}
                                        onPageChange={(nextPage) => setPage(nextPage)}
                                        recordsPerPageOptions={PAGE_SIZES}
                                        onRecordsPerPageChange={(size) => {
                                            setPageSize(size);
                                            setPage(1);
                                        }}
                                        paginationText={({ from, to, totalRecords: total }) =>
                                            `Showing ${from} to ${to} of ${total} customers`
                                        }
                                    />
                                )}
                            </div>
                        </div>
                    </div>

                    <Transition appear show={Boolean(detail)} as={Fragment}>
                        <Dialog as="div" open={Boolean(detail)} onClose={() => setDetail(null)} className="relative z-50">
                            <Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="ease-in duration-200" leaveFrom="opacity-100" leaveTo="opacity-0">
                                <div className="fixed inset-0 bg-[black]/60" />
                            </Transition.Child>
                            <div className="fixed inset-0 overflow-y-auto">
                                <div className="flex min-h-full items-center justify-center px-4 py-8">
                                    <Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0 scale-95" enterTo="opacity-100 scale-100" leave="ease-in duration-200" leaveFrom="opacity-100 scale-100" leaveTo="opacity-0 scale-95">
                                        <Dialog.Panel className="panel w-full max-w-4xl overflow-hidden rounded-lg border-0 p-0 text-black dark:text-white-dark">
                                            <button type="button" onClick={() => setDetail(null)} className="absolute top-4 text-gray-400 outline-none hover:text-gray-800 ltr:right-4 rtl:left-4 dark:hover:text-gray-600">
                                                x
                                            </button>
                                            <div className="bg-[#fbfbfb] py-3 text-lg font-medium ltr:pl-5 ltr:pr-[50px] rtl:pl-[50px] rtl:pr-5 dark:bg-[#121c2c]">
                                                Wishlist Detail
                                            </div>
                                            {detail && (
                                                <>
                                                    <div className="border-b border-white-dark/10 bg-white-dark/5 p-5 dark:bg-black/20">
                                                        <div className="grid gap-3 text-sm md:grid-cols-2">
                                                            <div>
                                                                <span className="text-gray-500">Nama:</span>{' '}
                                                                <span className="font-semibold">{detail.user?.name || detail.visitor_id}</span>
                                                            </div>
                                                            <div>
                                                                <span className="text-gray-500">Email:</span>{' '}
                                                                <span className="font-semibold">{detail.user?.email || '-'}</span>
                                                            </div>
                                                            <div>
                                                                <span className="text-gray-500">Phone:</span>{' '}
                                                                <span className="font-semibold">{detail.user?.phone || '-'}</span>
                                                            </div>
                                                            <div>
                                                                <span className="text-gray-500">Visitor:</span>{' '}
                                                                <span className="font-semibold">{detail.visitor_id}</span>
                                                            </div>
                                                        </div>
                                                    </div>
                                                    <div className="grid gap-4 p-5 md:grid-cols-2">
                                                        <div>
                                                            <h6 className="mb-2 font-semibold">Items</h6>
                                                            <div className="space-y-3">
                                                                {detail.items.map((item) => (
                                                                    <div key={`${item.product_id}-${item.added_at}`} className="text-xs">
                                                                        <div className="font-semibold">{itemTitle(item)}</div>
                                                                        <div>{item.product_sku || '-'}</div>
                                                                        <div>Masuk: {formatDateTime(item.added_at)}{item.added_at_estimated ? ' (perkiraan)' : ''}</div>
                                                                        <div>Lama: {formatDuration(item.duration_ms)} · Lihat: {item.view_count}</div>
                                                                        <div>Cart: {item.moved_to_cart_at ? formatDateTime(item.moved_to_cart_at) : '-'}</div>
                                                                        <div>Status: {item.status}</div>
                                                                    </div>
                                                                ))}
                                                            </div>
                                                        </div>
                                                        <div>
                                                            <h6 className="mb-2 font-semibold">Conversion Result</h6>
                                                            {(detail.conversions || []).length === 0 ? (
                                                                <span className="text-xs text-gray-500">Belum checkout</span>
                                                            ) : (
                                                                detail.conversions.map((entry) => (
                                                                    <div key={entry.order_id} className="mb-4 text-xs">
                                                                        {entry.match_type === 'partial' ? (
                                                                            <span className="badge bg-info">Partial</span>
                                                                        ) : (
                                                                            <span className="badge bg-success">Full convert</span>
                                                                        )}
                                                                        <p className="mt-2">
                                                                            Order:{' '}
                                                                            <Link href={`/orders/edit/${entry.order_id}`} className="underline">
                                                                                #{entry.order_id}
                                                                            </Link>
                                                                        </p>
                                                                        <p>Checkout: {formatDateTime(entry.converted_at)}</p>
                                                                        <p>Jalur: {entry.path || '-'}</p>
                                                                        <div className="mt-2">
                                                                            <Link href={sessionHref(detail.visitor_id)} className="underline">
                                                                                Sesi
                                                                            </Link>
                                                                            {detail.user ? (
                                                                                <Link href="/notification/abandoned-cart" className="ml-3 underline">
                                                                                    Abandoned cart
                                                                                </Link>
                                                                            ) : null}
                                                                        </div>
                                                                    </div>
                                                                ))
                                                            )}
                                                        </div>
                                                    </div>
                                                </>
                                            )}
                                        </Dialog.Panel>
                                    </Transition.Child>
                                </div>
                            </div>
                        </Dialog>
                    </Transition>
                </>
            )}
        </>
    );
};

export default WishlistNotification;
