import { useEffect, useState, Fragment } from 'react';
import { useDispatch } from 'react-redux';
import 'mantine-datatable/styles.css';
import Link from 'next/link';
import { DataTable, type DataTableSortStatus } from '@/components/Shared/DataTable';

import { setPageTitle } from '../../../store/themeConfigSlice';
import { coloredToast, progressToast } from '@/lib/toast';
import { DateRange, StatsPreset, getDefaultStatsDateRange, getPreviousPeriodRange } from '@/lib/abandoned-cart-stats-date';
import { ANALYTICS_STATS_PREFS_KEYS, loadSimpleStatsPrefs, saveSimpleStatsPrefs } from '@/lib/analytics-stats-prefs';
import AbandonedCartStatsPanel, { AbandonedCartStats } from '@/components/AbandonedCart/AbandonedCartStatsPanel';
import StatsDateRangePicker from '@/components/AbandonedCart/StatsDateRangePicker';

import { Dialog, Transition } from '@headlessui/react';

type CartStatus = 'active' | 'empty' | 'converted';
type ViewTab = CartStatus | 'wa-pending' | 'statistics';
type ConvertedOutcome = 'all' | 'success' | 'failed';
type WaPendingStatus = 'pending' | 'sent' | 'expired' | 'cancelled' | 'all';
type BlockReason = 'invalid_product' | 'all_out_of_stock' | 'majority_out_of_stock';

interface WaPendingRecord {
    id: string;
    abandoned_cart_id?: { id?: string; status?: string; last_synced_at?: string } | string;
    user_id?: { name?: string; email?: string; phone?: string } | string;
    items_snapshot: CartItem[];
    block_reason: BlockReason;
    in_stock_count: number;
    out_of_stock_count: number;
    invalid_count: number;
    last_synced_at?: string;
    expires_at?: string;
    last_stock_check_at?: string;
    status: Exclude<WaPendingStatus, 'all'>;
    resolved_at?: string;
    resolved_note?: string;
    createdAt: Date;
    updatedAt: Date;
}

interface CartItem {
    product?: { product_title?: string } | string;
    product_title?: string;
    attributeSelected?: Record<string, string>;
    attributeSelectedDisplay?: Record<string, string>;
    customText?: Record<string, string>;
    qty: number;
    _id?: string;
}

interface ConversionInfo {
    order_id?: string;
    converted_at?: string;
    match_type?: 'full' | 'partial' | 'none';
    matched_items?: CartItem[];
    unmatched_cart_items?: CartItem[];
    order_status?: string;
    order_outcome?: 'success' | 'failed' | 'pending' | 'unknown';
    purchased_items?: { product_title?: string; qty?: number }[];
}

interface AbandonedCart {
    id: string;
    cart_id?: string;
    _id?: string;
    user: {
        name: string;
        email: string;
        phone: string;
    };
    items: CartItem[];
    current_items?: CartItem[];
    checkout_items?: CartItem[];
    items_at_notification?: CartItem[];
    status?: CartStatus;
    last_synced_at?: string;
    last_notified_at?: string;
    conversion?: ConversionInfo;
    is_archived_conversion?: boolean;
    logs: {
        description: string;
        date_time: Date;
        items_snapshot?: CartItem[];
    }[];
    createdAt: Date;
    updatedAt: Date;
    wa_cron_eligible?: boolean;
    wa_eligible_reason?: string;
    wa_send_count?: number;
}

const OUTDATED_SYNC_DAYS = 30;
const OUTDATED_SYNC_TOOLTIP =
    'Cart user mungkin sudah berubah karena belum buka site atau login lebih dari 30 hari.';

const BLOCK_REASON_LABELS: Record<BlockReason, string> = {
    invalid_product: 'Produk tidak valid',
    all_out_of_stock: 'Semua stok habis',
    majority_out_of_stock: 'Mayoritas stok habis',
};

const WA_PENDING_STATUS_LABELS: Record<Exclude<WaPendingStatus, 'all'>, string> = {
    pending: 'Menunggu',
    sent: 'Terkirim',
    expired: 'Kedaluwarsa',
    cancelled: 'Dibatalkan',
};

const getPendingUser = (record: WaPendingRecord) => {
    if (record.user_id && typeof record.user_id === 'object') {
        return record.user_id;
    }
    return { name: '', email: '', phone: '' };
};

const getPendingCartId = (record: WaPendingRecord) => {
    if (!record.abandoned_cart_id) return '';
    if (typeof record.abandoned_cart_id === 'object') {
        return String(record.abandoned_cart_id.id || '');
    }
    return String(record.abandoned_cart_id);
};

const getBlockReasonBadge = (reason: BlockReason) => {
    const className =
        reason === 'invalid_product'
            ? 'bg-danger'
            : reason === 'all_out_of_stock'
                ? 'bg-warning'
                : 'bg-info';
    return <span className={`badge ${className}`}>{BLOCK_REASON_LABELS[reason] || reason}</span>;
};

const getPendingStatusBadge = (status: WaPendingRecord['status']) => {
    const className =
        status === 'pending'
            ? 'bg-warning'
            : status === 'sent'
                ? 'bg-success'
                : status === 'cancelled'
                    ? 'bg-secondary'
                    : 'bg-gray-500';
    return <span className={`badge ${className}`}>{WA_PENDING_STATUS_LABELS[status] || status}</span>;
};

const formatDaysRemaining = (expiresAt?: string) => {
    if (!expiresAt) return '-';
    const diffMs = new Date(expiresAt).getTime() - Date.now();
    if (diffMs <= 0) return 'Habis';
    const days = Math.ceil(diffMs / (1000 * 60 * 60 * 24));
    return `${days} hari`;
};

const canSendWhatsapp = (record: AbandonedCart) =>
    Boolean(record.user?.phone) && record.items.length > 0 && record.status !== 'converted';

const canBulkSelectWhatsapp = (record: AbandonedCart) =>
    canSendWhatsapp(record) && Boolean(record.wa_cron_eligible);

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

const isOutdatedSync = (lastSyncedAt?: string) => {
    if (!lastSyncedAt) return true;
    const synced = new Date(lastSyncedAt);
    const threshold = new Date();
    threshold.setDate(threshold.getDate() - OUTDATED_SYNC_DAYS);
    return synced < threshold;
};

const isFallbackProductTitle = (title?: string) => /^Product [a-f0-9]{6}$/i.test(String(title || '').trim());

const formatDuration = (from?: string | Date, to?: string | Date) => {
    if (!from || !to) return '-';
    const diffMs = new Date(to).getTime() - new Date(from).getTime();
    if (diffMs < 0) return '-';

    const days = Math.floor(diffMs / (1000 * 60 * 60 * 24));
    const hours = Math.floor((diffMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));

    if (days > 0) return `${days} hari ${hours} jam`;
    if (hours > 0) return `${hours} jam ${minutes} menit`;
    return `${minutes} menit`;
};

const getItemAttributes = (item: CartItem) => item.attributeSelectedDisplay || item.attributeSelected || {};

const getItemTitle = (item: CartItem) => {
    if (item.product_title && !isFallbackProductTitle(item.product_title)) {
        return item.product_title;
    }
    if (typeof item.product === 'object' && item.product?.product_title && !isFallbackProductTitle(item.product.product_title)) {
        return item.product.product_title;
    }
    if (item.product_title) return item.product_title;
    return 'Produk tidak ditemukan';
};

const getOrderStatusBadge = (orderStatus?: string) => {
    if (!orderStatus) return null;

    const className =
        orderStatus === 'Completed'
            ? 'bg-success'
            : orderStatus === 'Processing' || orderStatus === 'Indelivery'
                ? 'bg-info'
                : orderStatus === 'Canceled' || orderStatus === 'Failed'
                    ? 'bg-danger'
                    : 'bg-secondary';

    return <span className={`badge ${className} ml-1`}>{orderStatus}</span>;
};

const getCartItemKey = (item: CartItem, index: number) => {
    if (item._id) return String(item._id);

    const productId =
        typeof item.product === 'object'
            ? item.product?.product_title || 'product'
            : String(item.product || 'product');
    const attrs = JSON.stringify(item.attributeSelected || {});
    const custom = JSON.stringify(item.customText || {});

    return `${productId}-${attrs}-${custom}-${item.qty}-${index}`;
};

const resolveCartRecordId = (record: AbandonedCart) => {
    const rawId = String(record.cart_id || record._id || record.id || '').trim();

    if (!rawId) return '';

    return rawId.replace(/-(current|history-\d+)$/, '');
};

const normalizeAbandonedCartRecord = (record: AbandonedCart): AbandonedCart => {
    const cartId = resolveCartRecordId(record);

    return {
        ...record,
        id: String(record.id || cartId),
        cart_id: cartId,
    };
};

const renderItemList = (items: CartItem[] = []) => {
    if (!items.length) return <span className="text-xs text-gray-500">no items</span>;

    return (
        <>
            {items.map((item, index) => {
                const attrs = getItemAttributes(item);
                return (
                    <div key={getCartItemKey(item, index)} className="text-xs">
                        {getItemTitle(item)}
                        {Object.keys(attrs).length > 0 && (
                            <>
                                {' '}
                                |{' '}
                                {Object.entries(attrs)
                                    .map(([key, value]) => `${key}: ${value}`)
                                    .join(', ')}
                            </>
                        )}{' '}
                        | x{item.qty}
                    </div>
                );
            })}
        </>
    );
};

const getConversionBadge = (record: AbandonedCart) => {
    if (record.status !== 'converted' || !record.conversion) {
        if (record.status === 'empty') {
            return <span className="badge bg-gray-500">Cart empty</span>;
        }
        return <span className="badge bg-warning">Not converted</span>;
    }

    const { match_type, matched_items = [], unmatched_cart_items = [] } = record.conversion;
    const matched = matched_items?.length || 0;
    const total = matched + (unmatched_cart_items?.length || 0);

    if (match_type === 'full') {
        return <span className="badge bg-success">Full convert</span>;
    }
    if (match_type === 'partial') {
        return (
            <span className="badge bg-info">
                Partial ({matched}/{total || matched})
            </span>
        );
    }
    return <span className="badge bg-secondary">Converted (other items)</span>;
};

const postAbandonedCartSendWa = async (record: Pick<AbandonedCart, 'id' | 'cart_id'>) => {
    const cartId = resolveCartRecordId(record as AbandonedCart);
    if (!cartId) {
        throw new Error('Invalid abandoned cart ID');
    }

    const api_url = process.env.API_URL;
    const response = await fetch(`${api_url}api/abandoned-cart/send-wa/${cartId}`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        credentials: 'include',
    });

    const data = await response.json().catch(() => ({}));

    if (!response.ok) {
        throw new Error(data?.message || 'Whatsapp notification fail');
    }

    return data;
};

const formatExcelItem = (item: CartItem) => {
    const attrs = Object.entries(getItemAttributes(item))
        .map(([key, value]) => `${key}: ${value}`)
        .join(', ');
    const qty = Number(item.qty) > 0 ? ` x${item.qty}` : '';
    const title = getItemTitle(item);
    return attrs ? `${title} (${attrs})${qty}` : `${title}${qty}`;
};

const excelItemKey = (item: CartItem) => {
    const attrs = Object.entries(getItemAttributes(item))
        .map(([key, value]) => `${key}: ${value}`)
        .join(', ');
    const title = getItemTitle(item);
    return attrs ? `${title} (${attrs})` : title;
};

const DETAIL_HEADERS = [
    'name',
    'email',
    'phone',
    'status',
    'order_status',
    'order_outcome',
    'items_saat_wa',
    'items_di_checkout',
    'last_notified_at',
    'converted_at',
    'durasi_wa_ke_checkout',
    'last_synced_at',
    'match_type',
    'order_id',
    'matched_count',
    'unmatched_count',
    'created_at',
    'updated_at',
];

const ITEM_COLUMNS = new Set(['items_saat_wa', 'items_di_checkout']);

function buildCheckoutLabels(data: AbandonedCart) {
    if (data.status !== 'converted' || !data.conversion) return [];
    if (data.conversion.match_type === 'none') {
        const purchased = data.conversion.purchased_items || [];
        if (!purchased.length) return ['CO barang lain'];
        return purchased.map((item) => {
            const name = item.product_title || 'barang lain';
            const qty = Number(item.qty) > 0 ? ` x${item.qty}` : '';
            return `CO barang lain (${name}${qty})`;
        });
    }
    return (data.conversion.matched_items || []).map((item) => formatExcelItem(item));
}

function buildDetailRows(data: AbandonedCart[], forConvertedTab: boolean) {
    const rows: (string | number)[][] = [DETAIL_HEADERS];
    const merges: { s: { r: number; c: number }; e: { r: number; c: number } }[] = [];

    data.forEach((record) => {
        const waItems = (forConvertedTab ? record.items_at_notification || record.items || [] : record.items || []).map(
            (item) => formatExcelItem(item)
        );
        const checkoutItems = buildCheckoutLabels(record);
        const matchedRaw = record.conversion?.match_type === 'none' ? [] : record.conversion?.matched_items || [];
        const used = new Set<number>();
        const paired: { wa: string; co: string }[] = [];

        const waSource = forConvertedTab ? record.items_at_notification || record.items || [] : record.items || [];
        if (record.conversion?.match_type === 'none' || record.status !== 'converted') {
            const count = Math.max(waItems.length, checkoutItems.length, 1);
            for (let index = 0; index < count; index += 1) {
                paired.push({ wa: waItems[index] || '', co: checkoutItems[index] || '' });
            }
        } else {
            waSource.forEach((item, index) => {
                const key = excelItemKey(item);
                let matchIndex = matchedRaw.findIndex(
                    (candidate, candidateIndex) => !used.has(candidateIndex) && excelItemKey(candidate) === key
                );
                if (matchIndex < 0) {
                    matchIndex = matchedRaw.findIndex(
                        (candidate, candidateIndex) => !used.has(candidateIndex) && getItemTitle(candidate) === getItemTitle(item)
                    );
                }
                if (matchIndex >= 0) used.add(matchIndex);
                paired.push({
                    wa: waItems[index] || formatExcelItem(item),
                    co: matchIndex >= 0 ? formatExcelItem(matchedRaw[matchIndex]) : '',
                });
            });
            matchedRaw.forEach((item, index) => {
                if (used.has(index)) return;
                paired.push({ wa: '', co: formatExcelItem(item) });
            });
            if (!paired.length) paired.push({ wa: '', co: '' });
        }

        const shared = {
            name: record.user?.name || '',
            email: record.user?.email || '',
            phone: record.user?.phone || '',
            status: record.status || 'active',
            order_status: record.conversion?.order_status || '',
            order_outcome: record.conversion?.order_outcome || '',
            last_notified_at: record.last_notified_at || '',
            converted_at: record.conversion?.converted_at || '',
            durasi_wa_ke_checkout:
                record.status === 'converted' ? formatDuration(record.last_notified_at, record.conversion?.converted_at) : '',
            last_synced_at: forConvertedTab ? '' : record.last_synced_at || '',
            match_type: record.conversion?.match_type || '',
            order_id: record.conversion?.order_id || '',
            matched_count: record.conversion?.matched_items?.length || 0,
            unmatched_count: record.conversion?.unmatched_cart_items?.length || 0,
            created_at: record.createdAt ? String(record.createdAt) : '',
            updated_at: record.updatedAt ? String(record.updatedAt) : '',
        };

        const start = rows.length;
        paired.forEach((line, index) => {
            rows.push(
                DETAIL_HEADERS.map((header) => {
                    if (header === 'items_saat_wa') return line.wa;
                    if (header === 'items_di_checkout') return line.co;
                    if (index > 0) return '';
                    return shared[header as keyof typeof shared] ?? '';
                })
            );
        });
        if (paired.length > 1) {
            DETAIL_HEADERS.forEach((header, column) => {
                if (ITEM_COLUMNS.has(header)) return;
                merges.push({
                    s: { r: start, c: column },
                    e: { r: start + paired.length - 1, c: column },
                });
            });
        }
    });

    return { rows, merges };
}

function addProductStat(
    map: Map<string, { barang: string; jumlah_cart: number; total_qty: number; carts: Set<string> }>,
    item: CartItem,
    cartId: string
) {
    const key = excelItemKey(item);
    if (!key) return;
    const current = map.get(key) || { barang: key, jumlah_cart: 0, total_qty: 0, carts: new Set<string>() };
    if (!current.carts.has(cartId)) {
        current.carts.add(cartId);
        current.jumlah_cart += 1;
    }
    current.total_qty += Number(item.qty) > 0 ? Number(item.qty) : 1;
    map.set(key, current);
}

function statsSheet(map: Map<string, { barang: string; jumlah_cart: number; total_qty: number }>) {
    const body = [...map.values()]
        .sort((a, b) => b.jumlah_cart - a.jumlah_cart || b.total_qty - a.total_qty)
        .map((row) => [row.barang, row.jumlah_cart, row.total_qty]);
    return [['barang', 'jumlah_cart', 'total_qty'], ...body];
}

function buildProductSheets(activeRows: AbandonedCart[], convertedRows: AbandonedCart[]) {
    const checkedOut = new Map<string, { barang: string; jumlah_cart: number; total_qty: number; carts: Set<string> }>();
    const notBought = new Map<string, { barang: string; jumlah_cart: number; total_qty: number; carts: Set<string> }>();
    const afterWa = new Map<string, { barang: string; jumlah_cart: number; total_qty: number; carts: Set<string> }>();

    activeRows.forEach((record) => {
        const cartId = String(record.cart_id || record.id || '');
        (record.items || []).forEach((item) => addProductStat(notBought, item, cartId));
    });

    convertedRows.forEach((record) => {
        const cartId = String(record.cart_id || record.id || '');
        const matchType = record.conversion?.match_type;
        const convertedAt = record.conversion?.converted_at;
        const boughtAfterWa =
            Boolean(record.last_notified_at) &&
            (!convertedAt || new Date(convertedAt).getTime() >= new Date(record.last_notified_at || 0).getTime());

        (record.conversion?.matched_items || []).forEach((item) => {
            addProductStat(checkedOut, item, cartId);
            if (boughtAfterWa) addProductStat(afterWa, item, cartId);
        });

        const skipped =
            matchType === 'none'
                ? record.items_at_notification || record.items || []
                : record.conversion?.unmatched_cart_items || [];
        skipped.forEach((item) => addProductStat(notBought, item, cartId));
    });

    return {
        checkedOut: statsSheet(checkedOut),
        notBought: statsSheet(notBought),
        afterWa: statsSheet(afterWa),
    };
}

const WA_PENDING_HEADERS = [
    'name',
    'email',
    'phone',
    'status',
    'block_reason',
    'in_stock',
    'out_of_stock',
    'invalid',
    'expires_at',
    'item',
    'last_stock_check_at',
];

function buildWaPendingRows(records: WaPendingRecord[]) {
    const rows: (string | number)[][] = [WA_PENDING_HEADERS];
    const merges: { s: { r: number; c: number }; e: { r: number; c: number } }[] = [];

    records.forEach((record) => {
        const user = getPendingUser(record);
        const items = (record.items_snapshot || []).map((item) => formatExcelItem(item));
        const lines = items.length ? items : [''];
        const shared = {
            name: user.name || '',
            email: user.email || '',
            phone: user.phone || '',
            status: WA_PENDING_STATUS_LABELS[record.status] || record.status,
            block_reason: BLOCK_REASON_LABELS[record.block_reason] || record.block_reason,
            in_stock: record.in_stock_count ?? 0,
            out_of_stock: record.out_of_stock_count ?? 0,
            invalid: record.invalid_count ?? 0,
            expires_at: record.expires_at || '',
            last_stock_check_at: record.last_stock_check_at || '',
        };
        const start = rows.length;
        lines.forEach((item, index) => {
            rows.push(
                WA_PENDING_HEADERS.map((header) => {
                    if (header === 'item') return item;
                    if (index > 0) return '';
                    return shared[header as keyof typeof shared] ?? '';
                })
            );
        });
        if (lines.length > 1) {
            WA_PENDING_HEADERS.forEach((header, column) => {
                if (header === 'item') return;
                merges.push({
                    s: { r: start, c: column },
                    e: { r: start + lines.length - 1, c: column },
                });
            });
        }
    });

    return { rows, merges };
}

const AbandonedCartIndex = () => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(setPageTitle('Abandoned Cart'));
    }, [dispatch]);

    const [isMounted, setIsMounted] = useState(false);
    const [activeTab, setActiveTab] = useState<ViewTab>('active');
    const [convertedOutcome, setConvertedOutcome] = useState<ConvertedOutcome>('all');
    const [pendingStatus, setPendingStatus] = useState<WaPendingStatus>('pending');
    const [pendingBlockReason, setPendingBlockReason] = useState<BlockReason | ''>('');

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

    const [page, setPage] = useState(1);
    const PAGE_SIZES = [5, 10, 20, 30, 50, 100];
    const [pageSize, setPageSize] = useState(PAGE_SIZES[0]);
    const [records, setRecords] = useState<AbandonedCart[]>([]);
    const [pendingRecords, setPendingRecords] = useState<WaPendingRecord[]>([]);
    const [totalRecords, setTotalRecords] = useState(0);
    const [search, setSearch] = useState('');
    const [searchInput, setSearchInput] = useState('');

    const [isLoading, setIsLoading] = useState(true);
    const [isLoadingDownload, setIsLoadingDownload] = useState(false);
    const [bulkData, setBulkData] = useState<AbandonedCart[]>([]);
    const [isBulkButton, setIsBulkButton] = useState(false);
    const [isErrorData, setIsErrorData] = useState<string[]>([]);

    const [historyModal, setHistoryModal] = useState(false);
    const [historyData, setHistoryData] = useState<AbandonedCart['logs']>([]);

    const [detailModal, setDetailModal] = useState(false);
    const [detailData, setDetailData] = useState<AbandonedCart | null>(null);
    const [statsData, setStatsData] = useState<AbandonedCartStats | null>(null);
    const [compareStatsData, setCompareStatsData] = useState<AbandonedCartStats | null>(null);
    const [appliedStatsRange, setAppliedStatsRange] = useState<DateRange>(getDefaultStatsDateRange);
    const [appliedCompareRange, setAppliedCompareRange] = useState<DateRange | null>(null);
    const [statsPreset, setStatsPreset] = useState<StatsPreset>('last7');
    const [compareEnabled, setCompareEnabled] = useState(true);
    const [isStatsPickerOpen, setIsStatsPickerOpen] = useState(false);
    const [prefsHydrated, setPrefsHydrated] = useState(false);

    useEffect(() => {
        const saved = loadSimpleStatsPrefs(ANALYTICS_STATS_PREFS_KEYS.abandonedCart);
        setAppliedStatsRange(saved.range);
        setStatsPreset(saved.preset);
        setCompareEnabled(saved.compareEnabled);
        setPrefsHydrated(true);
    }, []);

    useEffect(() => {
        if (!prefsHydrated) return;
        saveSimpleStatsPrefs(ANALYTICS_STATS_PREFS_KEYS.abandonedCart, {
            range: appliedStatsRange,
            preset: statsPreset,
            compareEnabled,
        });
    }, [prefsHydrated, appliedStatsRange, statsPreset, compareEnabled]);
    const [selectedCoDay, setSelectedCoDay] = useState('0');
    const [sortStatus, setSortStatus] = useState<DataTableSortStatus<any>>({
        columnAccessor: 'last_notified_at',
        direction: 'desc',
    });

    const fetchAbandonedCartStats = async (range: DateRange): Promise<AbandonedCartStats> => {
        const api_url = process.env.API_URL;
        const params = new URLSearchParams({
            date_from: range.from,
            date_to: range.to,
        });
        const response = await fetch(`${api_url}api/abandoned-cart/stats?${params}`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
            credentials: 'include',
        });
        const data = await response.json();
        if (!response.ok) {
            throw new Error(data?.message || 'Gagal memuat statistik abandoned cart');
        }
        if (typeof data?.wa_sent_unique_users !== 'number') {
            throw new Error(data?.message || 'Format statistik tidak valid');
        }
        return data;
    };

    const fetchData = async () => {
        setIsLoading(true);
        try {
            const api_url = process.env.API_URL;
            if (activeTab === 'statistics') {
                if (compareEnabled) {
                    const compareRange = getPreviousPeriodRange(appliedStatsRange);
                    setAppliedCompareRange(compareRange);
                    const [currentStats, previousStats] = await Promise.all([
                        fetchAbandonedCartStats(appliedStatsRange),
                        fetchAbandonedCartStats(compareRange),
                    ]);
                    setStatsData(currentStats);
                    setCompareStatsData(previousStats);
                } else {
                    setAppliedCompareRange(null);
                    setCompareStatsData(null);
                    const currentStats = await fetchAbandonedCartStats(appliedStatsRange);
                    setStatsData(currentStats);
                }
                return;
            }

            if (activeTab === 'wa-pending') {
                const params = new URLSearchParams({
                    page: String(page),
                    per_page: String(pageSize),
                    status: pendingStatus,
                });
                if (search) params.set('q', search);
                if (pendingBlockReason) params.set('block_reason', pendingBlockReason);

                const response = await fetch(`${api_url}api/abandoned-cart/wa-pending/list?${params}`, {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    credentials: 'include',
                });
                const data = await response.json();

                setPage(data.currentPage);
                setTotalRecords(data.totalData);
                setPendingRecords(data.data || []);
                return;
            }

            const params = new URLSearchParams({
                page: String(page),
                per_page: String(pageSize),
                status: activeTab,
                q: search,
                sort_by: String(sortStatus.columnAccessor),
                sort_dir: sortStatus.direction,
            });
            if (activeTab === 'converted' && convertedOutcome !== 'all') {
                params.set('order_outcome', convertedOutcome);
            }

            const response = await fetch(`${api_url}api/abandoned-cart/list?${params}`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'include',
            });
            const data = await response.json();

            setPage(data.currentPage);
            setTotalRecords(data.totalData);
            setRecords((data.data || []).map(normalizeAbandonedCartRecord));
        } catch (error) {
            console.error('Error fetching data:', error);
            if (activeTab === 'statistics') {
                setStatsData(null);
                setCompareStatsData(null);
                coloredToast(
                    'warning',
                    error instanceof Error ? error.message : 'Gagal memuat statistik abandoned cart'
                );
            }
        } finally {
            setIsLoading(false);
        }
    };

    useEffect(() => {
        if (!prefsHydrated) return;
        fetchData();
    }, [prefsHydrated, page, pageSize, activeTab, sortStatus, search, pendingStatus, pendingBlockReason, convertedOutcome, appliedStatsRange, compareEnabled]);

    const handleSearchSubmit = () => {
        setSearch(searchInput.trim());
        setPage(1);
    };

    const handleSortStatusChange = (status: DataTableSortStatus<any>) => {
        setSortStatus(status);
        setPage(1);
    };

    const sendWhatsapp = async (record: AbandonedCart) => {
        try {
            await postAbandonedCartSendWa(record);
            fetchData();
            coloredToast('success', 'Whatsapp notification sent successfully');
        } catch (e: any) {
            coloredToast('warning', e.message);
        }
    };

    const retryPendingWhatsapp = async (record: WaPendingRecord) => {
        const cartId = getPendingCartId(record);
        if (!cartId) {
            coloredToast('warning', 'Abandoned cart ID tidak ditemukan');
            return;
        }

        try {
            await postAbandonedCartSendWa({ id: cartId, cart_id: cartId });
            fetchData();
            coloredToast('success', 'Whatsapp notification sent successfully');
        } catch (e: any) {
            coloredToast('warning', e.message);
        }
    };

    const setHistory = (logs: AbandonedCart['logs']) => {
        if (logs.length > 0) {
            setHistoryData(logs);
            setHistoryModal(true);
        }
    };

    const openDetail = (record: AbandonedCart) => {
        setDetailData(record);
        setDetailModal(true);
    };

    async function handleDownloadExcel(parts: {
        active: ReturnType<typeof buildDetailRows>;
        converted: ReturnType<typeof buildDetailRows>;
        pending: ReturnType<typeof buildWaPendingRows>;
        sheets: { checkedOut: (string | number)[][]; notBought: (string | number)[][]; afterWa: (string | number)[][] };
    }) {
        const XLSX = await import('xlsx');
        const workbook = XLSX.utils.book_new();
        const appendDetail = (name: string, detail: { rows: (string | number)[][]; merges: { s: { r: number; c: number }; e: { r: number; c: number } }[] }, headers: string[]) => {
            const sheet = XLSX.utils.aoa_to_sheet(detail.rows);
            sheet['!merges'] = detail.merges;
            sheet['!cols'] = headers.map((header) => ({ wch: header === 'items_saat_wa' || header === 'items_di_checkout' || header === 'item' ? 42 : 22 }));
            XLSX.utils.book_append_sheet(workbook, sheet, name);
        };
        appendDetail('Active', parts.active, DETAIL_HEADERS);
        appendDetail('Converted', parts.converted, DETAIL_HEADERS);
        appendDetail('WA Pending', parts.pending, WA_PENDING_HEADERS);

        const appendSummary = (name: string, rows: (string | number)[][]) => {
            const sheet = XLSX.utils.aoa_to_sheet(rows);
            sheet['!cols'] = [{ wch: 48 }, { wch: 16 }, { wch: 14 }];
            XLSX.utils.book_append_sheet(workbook, sheet, name);
        };
        appendSummary('Cart lalu checkout', parts.sheets.checkedOut);
        appendSummary('Cart tidak dibeli', parts.sheets.notBought);
        appendSummary('Dibeli setelah WA', parts.sheets.afterWa);
        XLSX.writeFile(workbook, 'Abandoned Cart.xlsx', { compression: true });
    }

    const fetchAllAbandoned = async (status: CartStatus | 'all' = 'all', orderOutcome: ConvertedOutcome = 'all') => {
        const api_url = process.env.API_URL;
        const params = new URLSearchParams({ status });
        if (status === 'converted' && orderOutcome !== 'all') {
            params.set('order_outcome', orderOutcome);
        }
        const response = await fetch(`${api_url}api/abandoned-cart/all?${params}`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
            credentials: 'include',
        });
        return await response.json();
    };

    const fetchAllWaPending = async () => {
        const api_url = process.env.API_URL;
        const rows: WaPendingRecord[] = [];
        let page = 1;
        let total = 0;
        do {
            const params = new URLSearchParams({
                page: String(page),
                per_page: '100',
                status: 'all',
            });
            const response = await fetch(`${api_url}api/abandoned-cart/wa-pending/list?${params}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'include',
            });
            const data = await response.json();
            rows.push(...(data.data || []));
            total = data.totalData || 0;
            page += 1;
        } while (rows.length < total && page < 100);
        return rows;
    };

    const handleDownload = async () => {
        setIsLoadingDownload(true);
        try {
            const [activeRows, convertedRows, pendingRows] = await Promise.all([
                fetchAllAbandoned('active'),
                fetchAllAbandoned('converted', 'all'),
                fetchAllWaPending(),
            ]);
            const active = Array.isArray(activeRows) ? activeRows : [];
            const converted = Array.isArray(convertedRows) ? convertedRows : [];
            handleDownloadExcel({
                active: buildDetailRows(active, false),
                converted: buildDetailRows(converted, true),
                pending: buildWaPendingRows(pendingRows),
                sheets: buildProductSheets(active, converted),
            });
        } catch (error) {
            coloredToast('warning', error instanceof Error ? error.message : 'Gagal mengunduh abandoned cart');
        } finally {
            setIsLoadingDownload(false);
        }
    };

    const sendBulkNotification = async (data: AbandonedCart[], delayMs: number) => {
        try {
            let count = 0;
            const errors: string[] = [];

            progressToast(`Sending Message`, count, data.length);

            for (const item of data) {
                await delay(delayMs);
                try {
                    await postAbandonedCartSendWa(item);
                    count++;
                    progressToast(`Sending Message `, count, data.length);
                } catch {
                    errors.push(item.cart_id || item.id);
                }
            }

            fetchData();
            setBulkData([]);
            setIsBulkButton(false);
            if (errors.length > 0) {
                coloredToast('warning', `Some Message is not send`);
            } else {
                coloredToast('success', 'All Whatsapp notifications has been sent');
            }
        } catch (e: any) {
            coloredToast('warning', e.message);
        }
    };

    const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

    const isConvertedView = activeTab === 'converted';
    const isWaPendingView = activeTab === 'wa-pending';
    const isStatisticsView = activeTab === 'statistics';

    const getWaItems = (record: AbandonedCart) =>
        record.items_at_notification || record.items || [];

    const getCheckoutItems = (record: AbandonedCart) =>
        record.checkout_items ||
        record.conversion?.matched_items ||
        getWaItems(record);

    const handleStatsFilterApply = (range: DateRange, preset: StatsPreset, nextCompareEnabled: boolean) => {
        setAppliedStatsRange(range);
        setStatsPreset(preset);
        setCompareEnabled(nextCompareEnabled);
        setIsStatsPickerOpen(false);
    };

    const handleTabChange = (tab: ViewTab) => {
        setActiveTab(tab);
        setPage(1);
        setBulkData([]);
        setIsBulkButton(false);
        setSearch('');
        setSearchInput('');
        setConvertedOutcome('all');
        setPendingStatus('pending');
        setPendingBlockReason('');
        setSortStatus({
            columnAccessor: 'last_notified_at',
            direction: 'desc',
        });
    };

    const handleConvertedOutcomeChange = (outcome: ConvertedOutcome) => {
        setConvertedOutcome(outcome);
        setPage(1);
    };

    return (
        <>
            {isMounted && (
                <>
                    <div className="mb-3">
                        <ul className="flex space-x-2 rtl:space-x-reverse">
                            <li>
                                <span>Abandoned Cart</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 === 'empty' ? 'btn-primary' : 'btn-outline-primary'}`}
                            onClick={() => handleTabChange('empty')}
                        >
                            Empty
                        </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 === 'wa-pending' ? 'btn-primary' : 'btn-outline-primary'}`}
                            onClick={() => handleTabChange('wa-pending')}
                        >
                            WA Pending
                        </button>
                        <button
                            type="button"
                            className={`btn btn-sm ${activeTab === 'statistics' ? 'btn-primary' : 'btn-outline-primary'}`}
                            onClick={() => handleTabChange('statistics')}
                        >
                            Statistik
                        </button>
                    </div>

                    {isConvertedView && (
                        <div className="mb-4 flex flex-wrap gap-2">
                            <button
                                type="button"
                                className={`btn btn-sm ${convertedOutcome === 'all' ? 'btn-secondary' : 'btn-outline-secondary'}`}
                                onClick={() => handleConvertedOutcomeChange('all')}
                            >
                                Semua
                            </button>
                            <button
                                type="button"
                                className={`btn btn-sm ${convertedOutcome === 'success' ? 'btn-success' : 'btn-outline-success'}`}
                                onClick={() => handleConvertedOutcomeChange('success')}
                            >
                                CO Sukses
                            </button>
                            <button
                                type="button"
                                className={`btn btn-sm ${convertedOutcome === 'failed' ? 'btn-danger' : 'btn-outline-danger'}`}
                                onClick={() => handleConvertedOutcomeChange('failed')}
                            >
                                CO Batal/Gagal
                            </button>
                        </div>
                    )}

                    {isWaPendingView && (
                        <div className="mb-4 flex flex-wrap items-center gap-2">
                            <select
                                className="form-select w-auto text-sm"
                                value={pendingStatus}
                                onChange={(e) => {
                                    setPendingStatus(e.target.value as WaPendingStatus);
                                    setPage(1);
                                }}
                            >
                                <option value="pending">Status: Menunggu</option>
                                <option value="sent">Status: Terkirim</option>
                                <option value="expired">Status: Kedaluwarsa</option>
                                <option value="cancelled">Status: Dibatalkan</option>
                                <option value="all">Status: Semua</option>
                            </select>
                            <select
                                className="form-select w-auto text-sm"
                                value={pendingBlockReason}
                                onChange={(e) => {
                                    setPendingBlockReason(e.target.value as BlockReason | '');
                                    setPage(1);
                                }}
                            >
                                <option value="">Semua alasan blokir</option>
                                <option value="invalid_product">Produk tidak valid</option>
                                <option value="all_out_of_stock">Semua stok habis</option>
                                <option value="majority_out_of_stock">Mayoritas stok habis</option>
                            </select>
                            <span className="text-xs text-gray-500">
                                Antrian otomatis retry via cron &amp; back-in-stock (max 7 hari)
                            </span>
                        </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={isWaPendingView ? 'Search by name, email, or phone' : 'Search by name or email'}
                                    value={searchInput}
                                    onChange={(e) => setSearchInput(e.target.value)}
                                    onKeyDown={(e) => {
                                        if (e.key === 'Enter') {
                                            handleSearchSubmit();
                                        }
                                    }}
                                />
                                <button className="btn btn-sm btn-outline-success flex items-center justify-center" onClick={handleDownload} disabled={isLoadingDownload}>
                                    {isLoadingDownload ? (
                                        <>
                                            <div className="h-4 w-4 animate-spin rounded-full border-2 border-solid border-current border-r-transparent"></div>
                                            <span className="ml-2">Downloading..</span>
                                        </>
                                    ) : (
                                        'Download Abandoned Cart'
                                    )}
                                </button>
                                {!isWaPendingView && isBulkButton ? (
                                    <button className="btn btn-sm btn-outline-info flex items-center justify-center" onClick={() => sendBulkNotification(bulkData, 800)}>
                                        Send Bulk Notification
                                    </button>
                                ) : null}
                            </>
                        )}
                    </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 ? (
                                    statsData ? (
                                        <AbandonedCartStatsPanel
                                            statsData={statsData}
                                            compareStatsData={compareStatsData}
                                            compareEnabled={compareEnabled}
                                            appliedStatsRange={appliedStatsRange}
                                            appliedCompareRange={appliedCompareRange}
                                            onOpenPicker={() => setIsStatsPickerOpen(true)}
                                            selectedCoDay={selectedCoDay}
                                            onSelectedCoDayChange={setSelectedCoDay}
                                        />
                                    ) : (
                                        <div className="flex justify-center py-4 text-center">
                                            <span className="ms-3">Tidak ada data statistik</span>
                                        </div>
                                    )
                                ) : isWaPendingView ? (
                                    <DataTable
                                        className="table-hover whitespace-nowrap"
                                        records={pendingRecords}
                                        idAccessor="id"
                                        minHeight={250}
                                        noRecordsText="No data found"
                                        columns={[
                                            {
                                                accessor: 'name',
                                                title: 'Name',
                                                render: (record) => (
                                                    <div className="font-semibold">{getPendingUser(record).name || '-'}</div>
                                                ),
                                            },
                                            {
                                                accessor: 'email',
                                                title: 'Email',
                                                render: (record) => <>{getPendingUser(record).email || '-'}</>,
                                            },
                                            {
                                                accessor: 'phone',
                                                title: 'Phone',
                                                render: (record) => <>{getPendingUser(record).phone || '-'}</>,
                                            },
                                            {
                                                accessor: 'items_snapshot',
                                                title: 'Items',
                                                render: (record) => renderItemList(record.items_snapshot || []),
                                            },
                                            {
                                                accessor: 'block_reason',
                                                title: 'Alasan Blokir',
                                                render: (record) => getBlockReasonBadge(record.block_reason),
                                            },
                                            {
                                                accessor: 'stock',
                                                title: 'Stok',
                                                render: (record) => (
                                                    <div className="text-xs">
                                                        <div>In: {record.in_stock_count}</div>
                                                        <div>Out: {record.out_of_stock_count}</div>
                                                        <div>Invalid: {record.invalid_count}</div>
                                                    </div>
                                                ),
                                            },
                                            {
                                                accessor: 'status',
                                                title: 'Status',
                                                render: (record) => getPendingStatusBadge(record.status),
                                            },
                                            {
                                                accessor: 'expires_at',
                                                title: 'Sisa Waktu',
                                                render: (record) => (
                                                    <div className="text-xs">
                                                        <div>{formatDaysRemaining(record.expires_at)}</div>
                                                        <div className="text-gray-500">Exp: {formatDateTime(record.expires_at)}</div>
                                                    </div>
                                                ),
                                            },
                                            {
                                                accessor: 'last_stock_check_at',
                                                title: 'Cek Stok Terakhir',
                                                render: (record) => (
                                                    <div className="text-xs">{formatDateTime(record.last_stock_check_at)}</div>
                                                ),
                                            },
                                            {
                                                accessor: 'action',
                                                title: 'Actions',
                                                render: (record) => {
                                                    const user = getPendingUser(record);
                                                    const canRetry =
                                                        record.status === 'pending' &&
                                                        Boolean(user.phone) &&
                                                        (record.items_snapshot?.length || 0) > 0;
                                                    return (
                                                        <div className="flex gap-1">
                                                            {canRetry && (
                                                                <button
                                                                    type="button"
                                                                    className="btn btn-sm btn-outline-success"
                                                                    title="Coba kirim WA manual"
                                                                    onClick={() => retryPendingWhatsapp(record)}
                                                                >
                                                                    Retry WA
                                                                </button>
                                                            )}
                                                        </div>
                                                    );
                                                },
                                            },
                                        ]}
                                        highlightOnHover
                                        totalRecords={totalRecords}
                                        recordsPerPage={pageSize}
                                        page={page}
                                        onPageChange={(p) => setPage(p)}
                                        recordsPerPageOptions={PAGE_SIZES}
                                        onRecordsPerPageChange={setPageSize}
                                        paginationText={({ from, to, totalRecords }) =>
                                            `Showing ${from} to ${to} of ${totalRecords} pending records`
                                        }
                                    />
                                ) : (
                                    <DataTable
                                        className="table-hover whitespace-nowrap"
                                        records={records}
                                        idAccessor="id"
                                        minHeight={250}
                                        noRecordsText="No data found"
                                        selectedRecords={bulkData}
                                        onSelectedRecordsChange={(selectedRecords) => {
                                            setBulkData(selectedRecords);
                                            setIsBulkButton(selectedRecords.length > 0);
                                        }}
                                        isRecordSelectable={(record) => canBulkSelectWhatsapp(record)}
                                        columns={[
                                            {
                                                accessor: 'name',
                                                sortable: true,
                                                render: ({ user }) => <div className="font-semibold">{user?.name || ''}</div>,
                                            },
                                            {
                                                accessor: 'email',
                                                render: ({ user }) => <>{user?.email || ''}</>,
                                            },
                                            {
                                                accessor: 'phone',
                                                render: ({ user }) => <>{user?.phone || ''}</>,
                                            },
                                            {
                                                accessor: 'items',
                                                title: 'Items',
                                                render: (record) =>
                                                    renderItemList(
                                                        isConvertedView ? getWaItems(record) : record.items
                                                    ),
                                            },
                                            {
                                                accessor: 'last_synced_at',
                                                title: isConvertedView ? 'Items di-checkout' : 'Last Sync Cart',
                                                sortable: true,
                                                render: (record) => {
                                                    const displayItems = isConvertedView
                                                        ? getCheckoutItems(record)
                                                        : record.current_items || record.items;
                                                    const dateLabel = isConvertedView
                                                        ? 'Checkout'
                                                        : 'Sync';
                                                    const dateValue = isConvertedView
                                                        ? record.conversion?.converted_at || record.last_synced_at
                                                        : record.last_synced_at;

                                                    return (
                                                        <div>
                                                            {renderItemList(displayItems)}
                                                            <div className="mt-1 text-xs text-gray-500">
                                                                {dateLabel}: {formatDateTime(dateValue)}
                                                                {!isConvertedView && isOutdatedSync(record.last_synced_at) && (
                                                                    <span
                                                                        className="ml-1 cursor-help badge bg-warning"
                                                                        title={OUTDATED_SYNC_TOOLTIP}
                                                                    >
                                                                        Data lama
                                                                    </span>
                                                                )}
                                                            </div>
                                                        </div>
                                                    );
                                                },
                                            },
                                            {
                                                accessor: 'conversion',
                                                title: 'Status',
                                                render: (record) => (
                                                    <>
                                                        {getConversionBadge(record)}
                                                        {isConvertedView && getOrderStatusBadge(record.conversion?.order_status)}
                                                        {record.wa_eligible_reason === 'unchanged_reminder' && (
                                                            <span className="ml-1 badge bg-info text-xs">Reminder eligible</span>
                                                        )}
                                                    </>
                                                ),
                                            },
                                            {
                                                accessor: 'order',
                                                title: 'Order',
                                                render: ({ conversion, status }) =>
                                                    status === 'converted' && conversion?.order_id ? (
                                                        <Link href={`/orders/edit/${conversion.order_id}`} className="text-xs underline">
                                                            #{conversion.order_id}
                                                        </Link>
                                                    ) : (
                                                        '-'
                                                    ),
                                            },
                                            {
                                                accessor: 'action',
                                                title: 'Actions',
                                                render: (record) => {
                                                    const isResend = record.logs.length > 0;
                                                    const sendCount = record.wa_send_count ?? 0;
                                                    return (
                                                        <div className="flex gap-1">
                                                            {canSendWhatsapp(record) && (
                                                                <button
                                                                    type="button"
                                                                    className="btn btn-sm btn-outline-success"
                                                                    title={
                                                                        sendCount >= 2
                                                                            ? 'Cap 2 kiriman tercapai — kirim manual (override)'
                                                                            : isResend
                                                                                ? 'Kirim ulang manual (override aturan cron)'
                                                                                : 'Kirim manual'
                                                                    }
                                                                    onClick={() => sendWhatsapp(record)}
                                                                >
                                                                    WA
                                                                </button>
                                                            )}
                                                            <button type="button" className="btn btn-sm btn-outline-info" onClick={() => openDetail(record)}>
                                                                Detail
                                                            </button>
                                                        </div>
                                                    );
                                                },
                                            },
                                            {
                                                accessor: 'last_notified_at',
                                                title: 'Last WA',
                                                sortable: true,
                                                textAlign: 'center',
                                                render: ({ last_notified_at, logs }) => {
                                                    const dateTime = last_notified_at || (logs.length > 0 ? logs[logs.length - 1]?.date_time : null);
                                                    if (!dateTime) return '-';
                                                    return <div className="text-xs">{formatDateTime(dateTime)}</div>;
                                                },
                                            },
                                            {
                                                accessor: 'logs',
                                                title: 'History',
                                                render: ({ logs }) => {
                                                    if (logs.length <= 0) return <>-</>;
                                                    return (
                                                        <button type="button" onClick={() => setHistory(logs)} className="btn btn-outline-info text-xs">
                                                            {logs.length} show
                                                        </button>
                                                    );
                                                },
                                            },
                                        ]}
                                        highlightOnHover
                                        totalRecords={totalRecords}
                                        recordsPerPage={pageSize}
                                        page={page}
                                        onPageChange={(p) => setPage(p)}
                                        recordsPerPageOptions={PAGE_SIZES}
                                        onRecordsPerPageChange={setPageSize}
                                        sortStatus={sortStatus}
                                        onSortStatusChange={handleSortStatusChange}
                                        paginationText={({ from, to, totalRecords }) =>
                                            `Showing ${from} to ${to} of ${totalRecords} customers`
                                        }
                                    />
                                )}
                            </div>
                        </div>
                    </div>

                    <Transition appear show={historyModal} as={Fragment}>
                        <Dialog as="div" open={historyModal} onClose={() => setHistoryModal(false)} 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-2xl overflow-hidden rounded-lg border-0 p-0 text-black dark:text-white-dark">
                                            <button type="button" onClick={() => setHistoryModal(false)} 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]">Log History</div>
                                            <div className="mt-4 max-h-[420px] overflow-y-auto p-5">
                                                {historyData
                                                    .slice()
                                                    .reverse()
                                                    .map((label, index) => (
                                                        <div
                                                            key={`${String(label.date_time)}-${label.description}-${index}`}
                                                            className="mb-4 border-b border-white-dark/10 pb-4"
                                                        >
                                                            <p className="text-sm font-semibold">{formatDateTime(label.date_time)}</p>
                                                            <p className="text-sm">{label.description}</p>
                                                            {label.items_snapshot && label.items_snapshot.length > 0 && (
                                                                <div className="mt-2 rounded border border-white-dark/10 p-2">
                                                                    <p className="mb-1 text-xs font-semibold">Items snapshot:</p>
                                                                    {renderItemList(label.items_snapshot)}
                                                                </div>
                                                            )}
                                                        </div>
                                                    ))}
                                            </div>
                                        </Dialog.Panel>
                                    </Transition.Child>
                                </div>
                            </div>
                        </Dialog>
                    </Transition>

                    <Transition appear show={detailModal} as={Fragment}>
                        <Dialog as="div" open={detailModal} onClose={() => setDetailModal(false)} 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={() => setDetailModal(false)} 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]">Conversion Detail</div>
                                            {detailData && (
                                                <>
                                                    {(detailData.status === 'converted' || detailData.is_archived_conversion) && (
                                                        <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">WA Terakhir:</span>{' '}
                                                                    <span className="font-semibold">{formatDateTime(detailData.last_notified_at)}</span>
                                                                </div>
                                                                <div>
                                                                    <span className="text-gray-500">Checkout:</span>{' '}
                                                                    <span className="font-semibold">{formatDateTime(detailData.conversion?.converted_at)}</span>
                                                                </div>
                                                                <div>
                                                                    <span className="text-gray-500">Durasi setelah WA:</span>{' '}
                                                                    <span className="font-semibold">
                                                                        {formatDuration(detailData.last_notified_at, detailData.conversion?.converted_at)}
                                                                    </span>
                                                                </div>
                                                                <div>
                                                                    <span className="text-gray-500">Status Order:</span>{' '}
                                                                    {getOrderStatusBadge(detailData.conversion?.order_status) || (
                                                                        <span>-</span>
                                                                    )}
                                                                </div>
                                                            </div>
                                                        </div>
                                                    )}
                                                    <div className="grid gap-4 p-5 md:grid-cols-3">
                                                        <div>
                                                            <h6 className="mb-2 font-semibold">
                                                                Items
                                                            </h6>
                                                            {renderItemList(
                                                                detailData.status === 'converted' || detailData.is_archived_conversion
                                                                    ? getWaItems(detailData)
                                                                    : detailData.items
                                                            )}
                                                            <p className="mt-2 text-xs text-gray-500">
                                                                WA: {formatDateTime(detailData.last_notified_at)}
                                                            </p>
                                                        </div>
                                                        <div>
                                                            <h6 className="mb-2 font-semibold">
                                                                {detailData.status === 'converted' || detailData.is_archived_conversion
                                                                    ? 'Items di-checkout'
                                                                    : 'Last Sync Cart'}
                                                            </h6>
                                                            {renderItemList(
                                                                detailData.status === 'converted' || detailData.is_archived_conversion
                                                                    ? getCheckoutItems(detailData)
                                                                    : detailData.current_items || detailData.items
                                                            )}
                                                            <p className="mt-2 text-xs text-gray-500">
                                                                {detailData.status === 'converted' || detailData.is_archived_conversion ? (
                                                                    <>Checkout: {formatDateTime(detailData.conversion?.converted_at)}</>
                                                                ) : (
                                                                    <>
                                                                        Sync: {formatDateTime(detailData.last_synced_at)}
                                                                        {isOutdatedSync(detailData.last_synced_at) && (
                                                                            <span
                                                                                className="ml-1 cursor-help badge bg-warning"
                                                                                title={OUTDATED_SYNC_TOOLTIP}
                                                                            >
                                                                                Data lama
                                                                            </span>
                                                                        )}
                                                                    </>
                                                                )}
                                                            </p>
                                                        </div>
                                                        <div>
                                                            <h6 className="mb-2 font-semibold">Conversion Result</h6>
                                                            {getConversionBadge(detailData)}
                                                            {detailData.conversion?.order_id &&
                                                                (detailData.status === 'converted' || detailData.is_archived_conversion) && (
                                                                    <p className="mt-2 text-sm">
                                                                        Order:{' '}
                                                                        <Link href={`/orders/edit/${detailData.conversion.order_id}`} className="underline">
                                                                            #{detailData.conversion.order_id}
                                                                        </Link>
                                                                    </p>
                                                                )}
                                                            {detailData.conversion?.matched_items && detailData.conversion.matched_items.length > 0 && (
                                                                <div className="mt-3">
                                                                    <p className="text-xs font-semibold">Matched:</p>
                                                                    {renderItemList(detailData.conversion.matched_items)}
                                                                </div>
                                                            )}
                                                            {detailData.conversion?.unmatched_cart_items && detailData.conversion.unmatched_cart_items.length > 0 && (
                                                                <div className="mt-3">
                                                                    <p className="text-xs font-semibold">Belum di-CO:</p>
                                                                    {renderItemList(detailData.conversion.unmatched_cart_items)}
                                                                </div>
                                                            )}
                                                        </div>
                                                    </div>
                                                </>
                                            )}
                                        </Dialog.Panel>
                                    </Transition.Child>
                                </div>
                            </div>
                        </Dialog>
                    </Transition>

                    <StatsDateRangePicker
                        isOpen={isStatsPickerOpen}
                        appliedRange={appliedStatsRange}
                        appliedPreset={statsPreset}
                        appliedCompareEnabled={compareEnabled}
                        onClose={() => setIsStatsPickerOpen(false)}
                        onApply={handleStatsFilterApply}
                    />
                </>
            )}
        </>
    );
};

export default AbandonedCartIndex;
