import { useCallback, useEffect, useState } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

import { DateRange, formatRangeLabel } from '@/lib/abandoned-cart-stats-date';
import type {
    AcquisitionActiveFilters,
    AcquisitionRowClickPayload,
    AcquisitionTableRowsByDimension,
} from './AcquisitionTable';
import JourneyAddWidgetSidebar from './JourneyAddWidgetSidebar';
import JourneyWidgetBody from './JourneyWidgetBody';
import JourneyWidgetShell from './JourneyWidgetShell';
import type { ItemReportPayload } from './AddToCartItemReport';
import {
    DEFAULT_JOURNEY_LAYOUT,
    JOURNEY_WIDGET_MAP,
    loadJourneyLayout,
    saveJourneyLayout,
    type JourneyLayoutItem,
    type JourneyLayoutState,
    type JourneyWidgetId,
    type JourneyWidgetSize,
} from './widget-registry';

export type PathMetricRow = {
    path: string;
    count?: number;
    page_views?: number;
    sessions?: number;
    active_users?: number;
    engaged_sessions?: number;
    checkout_sessions?: number;
        purchase_sessions?: number;
        checkout_users?: number;
        purchase_users?: number;
        purchase_orders?: number;
        engaged_users?: number;
        event_count?: number;
    avg_duration_min?: number;
    total_duration_ms?: number;
};

export interface JourneyStats {
    filters?: {
        date_from: string;
        date_to: string;
        timezone: string;
        exclude_bots?: boolean;
    };
    overview: {
        total_sessions: number;
        unique_visitors: number;
        unique_users: number;
        avg_pages_per_session: number;
        total_page_views?: number;
        total_event_count?: number;
        avg_duration_min: number;
        pct_ended_idle: number;
        pct_ended_pagehide: number;
        ended_idle?: number;
        ended_pagehide?: number;
        bots_excluded?: number;
        engaged_sessions?: number;
        not_engaged_sessions?: number;
        engagement_rate_percent?: number;
        engaged_users?: number;
    };
    funnel: {
        sessions: number;
        product: number;
        cart: number;
        checkout: number;
        purchase: number;
        product_rate_percent: number;
        cart_rate_percent: number;
        checkout_rate_percent: number;
        purchase_rate_percent: number;
        checkout_to_purchase_percent: number;
        users?: {
            total: number;
            product: number;
            cart: number;
            checkout: number;
            purchase: number;
            purchase_buyers?: number;
            product_rate_percent: number;
            cart_rate_percent: number;
            checkout_rate_percent: number;
            purchase_rate_percent: number;
            checkout_to_purchase_percent: number;
        };
    };
    top_entry_pages?: PathMetricRow[];
    top_exit_pages?: PathMetricRow[];
    /** Landing pages: entry page pertama kali session dimulai */
    top_pages?: PathMetricRow[];
    auth?: {
        login_start: number;
        login_success: number;
        login_success_rate_percent: number;
        signup_start: number;
        signup_success: number;
        signup_success_rate_percent: number;
    };
    exit_intent?: {
        modal_shown: number;
        unlock: number;
        unlock_rate_percent: number;
    };
    commerce?: {
        product_view_sessions: number;
        add_to_cart_sessions: number;
        begin_checkout_sessions: number;
        purchase_sessions: number;
        purchase_per_session_percent: number;
        purchase_per_checkout_percent: number;
        product_view_users?: number;
        add_to_cart_users?: number;
        begin_checkout_users?: number;
        purchase_users?: number;
        purchase_orders?: number;
        purchase_per_user_percent?: number;
        purchase_per_checkout_users_percent?: number;
        top_add_to_cart?: {
            product_id: string;
            product_slug: string;
            product_title?: string;
            views: number;
            add_to_cart: number;
        }[];
        top_products?: {
            product_id: string;
            product_slug: string;
            product_title?: string;
            views: number;
            add_to_cart: number;
        }[];
        voucher?: {
            apply_total: number;
            apply_success: number;
            success_rate_percent: number;
        };
    };
    wedding?: {
        preview_opens: number;
        preview_to_checkout: number;
        preview_to_purchase: number;
        checkout_rate_percent: number;
        purchase_rate_percent: number;
        preview_open_users?: number;
        preview_to_checkout_users?: number;
        preview_to_purchase_users?: number;
        checkout_rate_users_percent?: number;
        purchase_rate_users_percent?: number;
    };
    search?: {
        sessions_with_search: number;
        search_to_product_view: number;
        search_to_product_rate_percent: number;
        top_queries?: {
            query: string;
            impressions: number;
            clicks: number;
            ctr_percent: number;
        }[];
    };
    item_report?: ItemReportPayload;
    link_clicks?: {
        total: number;
        by_channel: { channel: string; count: number }[];
        daily: {
            days: string[];
            series: { name: string; data: number[] }[];
        };
    };
    acquisition?: {
        channels?: {
            channel_group: string;
            sessions: number;
            engaged_sessions: number;
            checkout_sessions: number;
            purchase_sessions: number;
            purchase_rate_percent: number;
            users?: number;
            checkout_users?: number;
            purchase_users?: number;
            purchase_orders?: number;
            purchase_rate_users_percent?: number;
        }[];
        trend?: {
            days: string[];
            series: { name: string; data: number[] }[];
        };
        trend_users?: {
            days: string[];
            series: { name: string; data: number[] }[];
        };
        top_campaigns?: {
            channel_group: string;
            utm_campaign: string;
            sessions: number;
            engaged_sessions: number;
            checkout_sessions: number;
            purchase_sessions: number;
            purchase_rate_percent: number;
            users?: number;
            checkout_users?: number;
            purchase_users?: number;
            purchase_orders?: number;
            purchase_rate_users_percent?: number;
        }[];
        available_event_types?: { type: string; count: number }[];
        table_rows?: {
            id: string;
            channel_group: string;
            utm_source: string;
            utm_medium: string;
            utm_campaign: string;
            sessions: number;
            event_count?: number;
            event_counts_by_type?: Record<string, number>;
            engaged_sessions: number;
            checkout_sessions: number;
            purchase_sessions: number;
            purchase_rate_percent: number;
            avg_duration_min?: number;
            engaged_sessions_per_active_user?: number;
            active_users?: number;
            users?: number;
            checkout_users?: number;
            purchase_users?: number;
            purchase_orders?: number;
            engaged_users?: number;
            purchase_rate_users_percent?: number;
            total_duration_ms?: number;
        }[];
        table_rows_by_dimension?: AcquisitionTableRowsByDimension;
    };
    overview_snapshot?: {
        previous_range?: { from: string; to: string };
        current?: {
            event_count: number;
            active_users: number;
            engaged_sessions: number;
            engaged_users?: number;
            purchases: number;
            purchases_users?: number;
            purchases_orders?: number;
        };
        previous?: {
            event_count: number;
            active_users: number;
            engaged_sessions: number;
            engaged_users?: number;
            purchases: number;
            purchases_users?: number;
            purchases_orders?: number;
        };
        change_percent?: {
            event_count: number;
            active_users: number;
            engaged_sessions: number;
            engaged_users?: number;
            purchases: number;
            purchases_users?: number;
            purchases_orders?: number;
        };
        series?: {
            current?: {
                days: string[];
                event_count: number[];
                active_users: number[];
                engaged_sessions: number[];
                engaged_users?: number[];
                purchases: number[];
                purchases_users?: number[];
                purchases_orders?: number[];
            };
            previous?: {
                days: string[];
                event_count: number[];
                active_users: number[];
                engaged_sessions: number[];
                engaged_users?: number[];
                purchases: number[];
                purchases_users?: number[];
                purchases_orders?: number[];
            };
        };
    };
}

interface JourneyStatsPanelProps {
    statsData: JourneyStats;
    appliedStatsRange: DateRange;
    onOpenPicker: () => void;
    acquisitionFilters?: AcquisitionActiveFilters;
    onAcquisitionRowClick?: (payload: AcquisitionRowClickPayload) => void;
    onAcquisitionFiltersChange?: (filters: AcquisitionActiveFilters) => void;
    onClearAcquisitionFilters?: () => void;
    onNavigateSection?: (section: 'acquisition' | 'sessions' | 'realtime') => void;
    isRefreshing?: boolean;
    compareEnabled?: boolean;
    compareStatsData?: JourneyStats | null;
    compareRange?: DateRange | null;
}

const JourneyStatsPanel = ({
    statsData,
    appliedStatsRange,
    onOpenPicker,
    acquisitionFilters,
    onAcquisitionRowClick,
    onAcquisitionFiltersChange,
    onClearAcquisitionFilters,
    onNavigateSection,
    isRefreshing,
    compareEnabled,
    compareStatsData,
    compareRange = null,
}: JourneyStatsPanelProps) => {
    const [layout, setLayout] = useState<JourneyLayoutState>(DEFAULT_JOURNEY_LAYOUT);
    const [hydrated, setHydrated] = useState(false);
    const [sidebarOpen, setSidebarOpen] = useState(false);

    useEffect(() => {
        setLayout(loadJourneyLayout());
        setHydrated(true);
    }, []);

    useEffect(() => {
        if (!hydrated) return;
        saveJourneyLayout(layout);
    }, [layout, hydrated]);

    const updateItems = useCallback((updater: (items: JourneyLayoutItem[]) => JourneyLayoutItem[]) => {
        setLayout((prev) => ({ ...prev, items: updater(prev.items) }));
    }, []);

    const handleMove = useCallback(
        (dragIndex: number, hoverIndex: number) => {
            updateItems((items) => {
                const next = [...items];
                const [dragItem] = next.splice(dragIndex, 1);
                if (!dragItem) return items;
                next.splice(hoverIndex, 0, dragItem);
                return next;
            });
        },
        [updateItems]
    );

    const handleChangeSize = useCallback(
        (id: JourneyWidgetId, size: JourneyWidgetSize) => {
            updateItems((items) => items.map((item) => (item.id === id ? { ...item, size } : item)));
        },
        [updateItems]
    );

    const handleRemove = useCallback(
        (id: JourneyWidgetId) => {
            updateItems((items) => items.filter((item) => item.id !== id));
        },
        [updateItems]
    );

    const handleAdd = useCallback(
        (id: JourneyWidgetId) => {
            const def = JOURNEY_WIDGET_MAP[id];
            if (!def) return;
            updateItems((items) => {
                if (items.some((i) => i.id === id)) return items;
                return [...items, { id, size: def.defaultSize }];
            });
        },
        [updateItems]
    );

    const handleReset = useCallback(() => {
        setLayout(DEFAULT_JOURNEY_LAYOUT);
    }, []);

    return (
        <div className="space-y-4">
            <div className="panel">
                <div className="flex flex-wrap items-center justify-between gap-3">
                    <div>
                        <h3 className="text-lg font-semibold">Ringkasan</h3>
                        <p className="text-sm text-gray-500">{formatRangeLabel(appliedStatsRange)}</p>
                    </div>
                    <div className="flex flex-wrap gap-2">
                        <button
                            type="button"
                            className="btn btn-primary"
                            onClick={() => setSidebarOpen((v) => !v)}
                        >
                            {sidebarOpen ? 'Tutup widget' : 'Add widget'}
                        </button>
                    </div>
                </div>
            </div>

            <div className="flex flex-col lg:flex-row gap-4 items-start">
                <div className="flex-1 w-full min-w-0">
                    {!layout.items.length ? (
                        <div className="panel text-sm text-gray-500">
                            Belum ada widget. Buka <strong>Add widget</strong> untuk menambah, atau reset ke
                            default.
                        </div>
                    ) : (
                        <DndProvider backend={HTML5Backend}>
                            <div className="grid grid-cols-12 gap-4">
                                {layout.items.map((item, index) => (
                                    <JourneyWidgetShell
                                        key={item.id}
                                        id={item.id}
                                        index={index}
                                        size={item.size}
                                        onMove={handleMove}
                                        onChangeSize={handleChangeSize}
                                        onRemove={handleRemove}
                                    >
                                        <JourneyWidgetBody
                                            id={item.id}
                                            statsData={statsData}
                                            acquisitionFilters={acquisitionFilters}
                                            onAcquisitionRowClick={onAcquisitionRowClick}
                                            onAcquisitionFiltersChange={onAcquisitionFiltersChange}
                                            onClearAcquisitionFilters={onClearAcquisitionFilters}
                                            onNavigateSection={onNavigateSection}
                                            isRefreshing={isRefreshing}
                                            compareEnabled={compareEnabled}
                                            compareStatsData={compareStatsData}
                                            dateRange={appliedStatsRange}
                                            compareRange={compareRange}
                                        />
                                    </JourneyWidgetShell>
                                ))}
                            </div>
                        </DndProvider>
                    )}
                </div>

                <JourneyAddWidgetSidebar
                    open={sidebarOpen}
                    items={layout.items}
                    onAdd={handleAdd}
                    onClose={() => setSidebarOpen(false)}
                    onReset={handleReset}
                />
            </div>
        </div>
    );
};

export default JourneyStatsPanel;
