import { useEffect, useRef, useState } from 'react';
import Select from 'react-select';
import AsyncSelect from 'react-select/async';
import FreeItemProductSelector from './FreeItemProductSelector';
import { getPriductCategories } from '@/lib/product-categories';
import NumberFormatter from '@/lib/ribuan';
import type { CategoryRewardBenefit, CategoryRewardBenefitType, CategoryRewardGroup } from '@/utils/saveCategoryReward';

const emptyBenefit = (): CategoryRewardBenefit => ({
    type: 'none',
    coupon_id: '',
    products: [],
    qty_mode: 'per_transaction',
});

export const createEmptyGroup = (): CategoryRewardGroup => ({
    id: `group_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`,
    name: '',
    include_categories: [],
    threshold: null,
    threshold_basis: 'subtotal',
    rule_combination: 'above_only',
    above_benefit: emptyBenefit(),
    below_benefit: emptyBenefit(),
});

interface CategoryRewardConfigProps {
    promotion: any;
    setPromotion: React.Dispatch<React.SetStateAction<any>>;
    isUpdate?: boolean;
}

const benefitLabel = (benefit?: CategoryRewardBenefit) => {
    if (benefit?.type === 'voucher') return 'Voucher';
    if (benefit?.type === 'free_item') {
        return `Free Item (${benefit?.qty_mode === 'per_qty' ? 'Per Qty' : 'Per Transaction'})`;
    }
    return 'None';
};

const buildBenefitPatch = (type: CategoryRewardBenefitType, current?: CategoryRewardBenefit): CategoryRewardBenefit => {
    if (type === 'voucher') {
        return {
            type: 'voucher',
            coupon_id: current?.coupon_id || '',
            products: [],
            qty_mode: 'per_transaction',
        };
    }
    if (type === 'free_item') {
        return {
            type: 'free_item',
            coupon_id: '',
            products: current?.products || [],
            qty_mode: current?.qty_mode || 'per_transaction',
        };
    }
    return emptyBenefit();
};

/** Stacking + Merch Scope (kolom detail kiri) */
export const CategoryRewardDetailFields: React.FC<CategoryRewardConfigProps> = ({ promotion, setPromotion }) => {
    const handleChange = (e: any) => {
        setPromotion((prev: any) => ({
            ...prev,
            [e.target.name]: e.target.value,
        }));
    };

    return (
        <>
            <div className="mt-4 flex items-start">
                <label htmlFor="crStacking" className="mb-0 mt-2 flex-1 ltr:mr-2 rtl:ml-2">
                    Kombinasi Benefit
                    
                </label>
                <select
                    id="crStacking"
                    name="promotion_stacking_mode"
                    value={
                        promotion.promotion_stacking_mode === 'discount_only'
                            ? 'prefer_discount'
                            : promotion.promotion_stacking_mode === 'merch_only'
                              ? 'prefer_merch'
                              : promotion.promotion_stacking_mode || 'prefer_discount'
                    }
                    onChange={handleChange}
                    className="form-input w-2/3 lg:w-[250px]"
                >
                    <option value="prefer_discount">Prioritas Voucher</option>
                    <option value="prefer_merch">Prioritas Free Item</option>
                    <option value="allow_both">Voucher + Free Item</option>
                </select>
            </div>

            <div className="mt-4 flex items-start">
                <label htmlFor="crMerchScope" className="mb-0 mt-2 flex-1 ltr:mr-2 rtl:ml-2">
                    Mode Perhitungan Hadiah
                    <p className="mt-1 text-xs font-normal text-gray-500">
                        Digunakan saat lebih dari satu group sama-sama memberikan hadiah. <br />
                        Per Transaksi = sistem menggunakan jumlah hadiah paling besar. <br />
                        Per Group = jumlah hadiah dari setiap group aktif akan dijumlahkan.
                    </p>
                </label>
                <select
                    id="crMerchScope"
                    name="promotion_merch_scope"
                    value={promotion.promotion_merch_scope || 'per_order'}
                    onChange={handleChange}
                    className="form-input w-2/3 lg:w-[250px]"
                >
                    <option value="per_order">Per Transaksi (Ambil Terbesar)</option>
                    <option value="per_group">Per Group (Akumulasi)</option>
                </select>
            </div>

            <div className="mt-4 flex items-center">
                <label htmlFor="crExitIntent" className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                    Trigger on Back Page
                    <p className="mt-1 text-xs font-normal text-gray-500">
                        Benefit (voucher + free item) hanya aktif setelah user hendak keluar dari checkout.
                    </p>
                </label>
                <label className="relative h-6 w-12">
                    <input
                        type="checkbox"
                        id="crExitIntent"
                        checked={Boolean(promotion.exit_intent_only)}
                        onChange={(e) =>
                            setPromotion((prev: any) => ({
                                ...prev,
                                exit_intent_only: e.target.checked,
                                exit_require_login: e.target.checked
                                    ? Boolean(prev.exit_require_login)
                                    : false,
                            }))
                        }
                        className="custom_switch peer absolute z-10 h-full w-full cursor-pointer opacity-0"
                    />
                    <span className="outline_checkbox bg-icon block h-full rounded-full border-2 border-[#ebedf2] before:absolute before:bottom-1 before:left-1 before:h-4 before:w-4 before:rounded-full before:bg-[#ebedf2] before:bg-[url(/assets/images/close.svg)] before:bg-center before:bg-no-repeat before:transition-all before:duration-300 peer-checked:border-primary peer-checked:before:left-7 peer-checked:before:bg-primary peer-checked:before:bg-[url(/assets/images/checked.svg)] dark:border-white-dark dark:before:bg-white-dark"></span>
                </label>
            </div>

            <div className="mt-4 flex items-center">
                <label htmlFor="crExitRequireLogin" className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                    Wajib Login / Daftar
                    <p className="mt-1 text-xs font-normal text-gray-500">
                        Aktif hanya jika Trigger on Back Page ON. Guest harus login/daftar dulu untuk unlock benefit.
                    </p>
                </label>
                <label className="relative h-6 w-12">
                    <input
                        type="checkbox"
                        id="crExitRequireLogin"
                        disabled={!promotion.exit_intent_only}
                        checked={Boolean(promotion.exit_intent_only && promotion.exit_require_login)}
                        onChange={(e) =>
                            setPromotion((prev: any) => ({
                                ...prev,
                                exit_require_login: e.target.checked,
                            }))
                        }
                        className="custom_switch peer absolute z-10 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed"
                    />
                    <span className="outline_checkbox bg-icon block h-full rounded-full border-2 border-[#ebedf2] before:absolute before:bottom-1 before:left-1 before:h-4 before:w-4 before:rounded-full before:bg-[#ebedf2] before:bg-[url(/assets/images/close.svg)] before:bg-center before:bg-no-repeat before:transition-all before:duration-300 peer-checked:border-primary peer-checked:before:left-7 peer-checked:before:bg-primary peer-checked:before:bg-[url(/assets/images/checked.svg)] dark:border-white-dark dark:before:bg-white-dark peer-disabled:opacity-50"></span>
                </label>
            </div>

            <p className="mt-3 text-xs text-gray-500">
                Catatan: tiap barang hanya dihitung di satu group (urutan group di form).
                <br />
                Beberapa voucher aktif → sistem memilih potongan terbesar.
                <br />
                Keranjang sudah punya voucher terpasang → voucher category reward tidak ditawarkan lagi (hadiah tetap bisa aktif).
            </p>
        </>
    );
};

/** Reward Groups editor (kolom kanan) */
export const CategoryRewardGroupsPanel: React.FC<CategoryRewardConfigProps> = ({ promotion, setPromotion, isUpdate = false }) => {
    const [categoryOptions, setCategoryOptions] = useState<any[]>([]);
    const [selectedCoupons, setSelectedCoupons] = useState<Record<string, any>>({});
    const couponCacheRef = useRef<Record<string, any>>({});

    useEffect(() => {
        const loadCategories = async () => {
            const res = await getPriductCategories();
            const options = Array.isArray(res)
                ? res.map((option: { category_name: string }) => ({
                      value: option.category_name,
                      label: option.category_name.charAt(0).toUpperCase() + option.category_name.slice(1),
                  }))
                : [];
            setCategoryOptions(options);
        };
        loadCategories();
    }, []);

    useEffect(() => {
        const groups = promotion.promotion_reward_groups || [];
        groups.forEach((group: CategoryRewardGroup) => {
            (['above', 'below'] as const).forEach((side) => {
                const benefit = side === 'above' ? group.above_benefit : group.below_benefit;
                const couponId = benefit?.type === 'voucher' ? benefit.coupon_id : '';
                if (!couponId || couponCacheRef.current[couponId]) return;
                loadCouponById(couponId).then((opt) => {
                    if (opt) {
                        couponCacheRef.current[couponId] = opt;
                        setSelectedCoupons((prev) => ({ ...prev, [`${group.id}:${side}`]: opt }));
                    }
                });
            });
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [isUpdate, promotion.promotion_reward_groups]);

    const loadCouponById = async (couponId: string) => {
        try {
            const api_url = process.env.API_URL;
            const response = await fetch(`${api_url}api/coupons/${couponId}`, {
                credentials: 'include',
            });
            if (!response.ok) return null;
            const data = await response.json();
            const coupon = data?.data || data;
            if (!coupon) return null;
            return {
                value: String(coupon.id || coupon._id),
                label: `${coupon.coupon_name}${
                    coupon.coupon_amount != null
                        ? ` — ${
                              coupon.coupon_type === 'percentage'
                                  ? coupon.coupon_amount + '%'
                                  : 'IDR ' + Number(coupon.coupon_amount).toLocaleString('id-ID')
                          }`
                        : ''
                }`,
            };
        } catch {
            return null;
        }
    };

    const loadCouponOptions = async (inputValue: string) => {
        if (!inputValue || inputValue.length < 1) return [];
        try {
            const api_url = process.env.API_URL;
            const response = await fetch(`${api_url}api/coupons/list?page=1&per_page=20&q=${encodeURIComponent(inputValue)}`, {
                credentials: 'include',
            });
            if (!response.ok) return [];
            const data = await response.json();
            const rows = Array.isArray(data?.data) ? data.data : [];
            return rows.map((coupon: any) => ({
                value: String(coupon.id || coupon._id),
                label: `${coupon.coupon_name}${
                    coupon.coupon_amount != null
                        ? ` — ${
                              coupon.coupon_type === 'percentage'
                                  ? coupon.coupon_amount + '%'
                                  : 'IDR ' + Number(coupon.coupon_amount).toLocaleString('id-ID')
                          }`
                        : ''
                }`,
            }));
        } catch {
            return [];
        }
    };

    const updateGroup = (groupId: string, patch: Partial<CategoryRewardGroup>) => {
        setPromotion((prev: any) => ({
            ...prev,
            promotion_reward_groups: (prev.promotion_reward_groups || []).map((g: CategoryRewardGroup) => (g.id === groupId ? { ...g, ...patch } : g)),
        }));
    };

    const setBenefit = (group: CategoryRewardGroup, side: 'above' | 'below', benefit: CategoryRewardBenefit) => {
        updateGroup(group.id, side === 'above' ? { above_benefit: benefit } : { below_benefit: benefit });
    };

    const addGroup = () => {
        setPromotion((prev: any) => ({
            ...prev,
            promotion_reward_groups: [...(prev.promotion_reward_groups || []), createEmptyGroup()],
        }));
    };

    const removeGroup = (groupId: string) => {
        setPromotion((prev: any) => ({
            ...prev,
            promotion_reward_groups: (prev.promotion_reward_groups || []).filter((g: CategoryRewardGroup) => g.id !== groupId),
        }));
    };

    const renderBenefitFields = (group: CategoryRewardGroup, side: 'above' | 'below') => {
        const benefit = side === 'above' ? group.above_benefit : group.below_benefit;
        const couponKey = `${group.id}:${side}`;

        return (
            <>
                <div className="mt-3 flex items-center">
                    <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">{side === 'above' ? 'Above Min. Purchase' : 'Below Min. Purchase'}</label>
                    <select
                        className="form-input w-2/3"
                        value={benefit?.type || 'none'}
                        onChange={(e) => {
                            const nextType = e.target.value as CategoryRewardBenefitType;
                            if (nextType !== 'voucher') {
                                setSelectedCoupons((prev) => {
                                    const next = { ...prev };
                                    delete next[couponKey];
                                    return next;
                                });
                            }
                            setBenefit(group, side, buildBenefitPatch(nextType, benefit));
                        }}
                    >
                        <option value="none">Tidak Ada</option>
                        <option value="voucher">Voucher</option>
                        <option value="free_item">Free Item</option>
                    </select>
                </div>

                {benefit?.type === 'voucher' && (
                    <div className="mt-3 flex items-start ml-8">
                        <label className="mb-0 mt-2 flex-1 ltr:mr-2 rtl:ml-2">Coupon</label>
                        <div className="w-2/3">
                            <AsyncSelect
                                cacheOptions
                                defaultOptions
                                loadOptions={loadCouponOptions}
                                value={selectedCoupons[couponKey] || null}
                                onChange={(opt: any) => {
                                    setSelectedCoupons((prev) => ({ ...prev, [couponKey]: opt }));
                                    setBenefit(group, side, {
                                        type: 'voucher',
                                        coupon_id: opt?.value || '',
                                        products: [],
                                        qty_mode: 'per_transaction',
                                    });
                                }}
                                placeholder="Search coupon..."
                            />
                        </div>
                    </div>
                )}

                {benefit?.type === 'free_item' && (
                    <>
                        <div className="mt-3 flex items-center ml-8">
                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Mode Jumlah Hadiah</label>
                            <select
                                className="form-input w-2/3"
                                value={benefit?.qty_mode || 'per_transaction'}
                                onChange={(e) =>
                                    setBenefit(group, side, {
                                        type: 'free_item',
                                        coupon_id: '',
                                        products: benefit?.products || [],
                                        qty_mode: e.target.value as 'per_transaction' | 'per_qty',
                                    })
                                }
                            >
                                <option value="per_transaction">Per Transaksi</option>
                                <option value="per_qty">Per Qty</option>
                            </select>
                        </div>
                        <div className="mt-3 flex items-start ml-8">
                            <label className="mb-0 mt-2 flex-1 ltr:mr-2 rtl:ml-2">Hadiah (Free Item)</label>
                            <div className="custom-select w-2/3">
                                <FreeItemProductSelector
                                    isUpdate={isUpdate}
                                    productId={(benefit?.products || []).map((p) => p.productId)}
                                    onProductChange={(productIds) =>
                                        setBenefit(group, side, {
                                            type: 'free_item',
                                            coupon_id: '',
                                            qty_mode: benefit?.qty_mode || 'per_transaction',
                                            products: productIds.map((productId) => ({
                                                productId,
                                                active: true,
                                            })),
                                        })
                                    }
                                />
                            </div>
                        </div>
                    </>
                )}
            </>
        );
    };

    const groups = promotion.promotion_reward_groups || [];

    return (
        <div className="mb-4 w-full lg:w-1/2">
            <div className="text-lg">Aturan Group:</div>
            <p className="mt-1 text-xs text-white-dark">Atur benefit per kategori produk: minimum belanja, voucher, dan hadiah.</p>
            <div className="mb-8 mt-2 table w-full">
                {groups.length <= 0 && <div className="py-4 text-center font-semibold">Belum ada group</div>}

                {groups.map((group: CategoryRewardGroup, index: number) => (
                    <div key={group.id} className="mb-6 border-b border-[#e0e6ed] pb-4 dark:border-[#1b2e4b]">
                        <div className="mb-2 flex items-center justify-between">
                            <div className="font-semibold">Group {index + 1}</div>
                            <button type="button" onClick={() => removeGroup(group.id)}>
                                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                                    <line x1="18" y1="6" x2="6" y2="18"></line>
                                    <line x1="6" y1="6" x2="18" y2="18"></line>
                                </svg>
                            </button>
                        </div>

                        <div className="mt-3 flex items-center">
                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Group Name</label>
                            <input type="text" className="form-input w-2/3" value={group.name || ''} placeholder="9k & Diamond" onChange={(e) => updateGroup(group.id, { name: e.target.value })} />
                        </div>

                        <div className="mt-3 flex items-start">
                            <label className="mb-0 mt-2 flex-1 ltr:mr-2 rtl:ml-2">Product Category </label>
                            <div className="w-2/3">
                                <Select
                                    isMulti
                                    options={categoryOptions}
                                    className="basic-multi-select"
                                    classNamePrefix="select"
                                    value={categoryOptions.filter((opt) => (group.include_categories || []).includes(opt.value))}
                                    onChange={(selected: any) =>
                                        updateGroup(group.id, {
                                            include_categories: (selected || []).map((s: any) => s.value),
                                        })
                                    }
                                />
                            </div>
                        </div>

                        <div className="mt-3 flex items-center">
                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                                Group Promotion Type
                               
                            </label>
                            <select
                                className="form-input w-2/3"
                                value={group.threshold_basis || 'subtotal'}
                                onChange={(e) =>
                                    updateGroup(group.id, {
                                        threshold_basis: e.target.value as CategoryRewardGroup['threshold_basis'],
                                    })
                                }
                            >
                                <option value="subtotal">Subtotal Group</option>
                                <option value="per_item">Per Item (harga satuan)</option>
                                <option value="qty">Qty (jumlah pcs)</option>
                            </select>
                        </div>

                        <div className="mt-3 flex items-center">
                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                                Min. Purchase
                                <p className="mt-1 text-xs font-normal text-gray-500">
                                    
                                </p>
                            </label>
                            <NumberFormatter
                                className="form-input w-2/3"
                                min={0}
                                value={Number(group.threshold) || 0}
                                placeholder={
                                    group.threshold_basis === 'qty'
                                        ? '2 (0 = selalu pakai benefit bawah)'
                                        : '1.500.000 (0 = selalu pakai benefit bawah)'
                                }
                                onChange={(value) =>
                                    updateGroup(group.id, {
                                        threshold: value === 0 ? null : value,
                                    })
                                }
                            />
                        </div>

                        <div className="mt-3 flex items-center">
                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                                Group Rules
                            </label>
                            <select
                                className="form-input w-2/3"
                                value={group.rule_combination || 'above_only'}
                                onChange={(e) =>
                                    updateGroup(group.id, {
                                        rule_combination: e.target.value as CategoryRewardGroup['rule_combination'],
                                    })
                                }
                            >
                                <option value="above_only">Above saja (default)</option>
                                <option value="below_only">Below saja</option>
                                <option value="combine">Gabung Above + Below</option>
                            </select>
                        </div>

                        {renderBenefitFields(group, 'above')}
                        {renderBenefitFields(group, 'below')}

                        <p className="mt-3 text-xs text-white-dark">
                            {(() => {
                                const minPurchase = Number(group.threshold) || 0;
                                const aboveLabel = benefitLabel(group.above_benefit);
                                const belowLabel = benefitLabel(group.below_benefit);
                                const basis = group.threshold_basis || 'subtotal';
                                const combo = group.rule_combination || 'above_only';
                                const basisText =
                                    basis === 'per_item' ? 'harga satuan' : basis === 'qty' ? 'qty group' : 'subtotal group';
                                if (minPurchase > 0) {
                                    const formatted = minPurchase.toLocaleString('id-ID');
                                    return `Contoh (${basisText}, ${combo}): ≥ ${formatted} → ${aboveLabel}; < ${formatted} → ${belowLabel}. Item yang sudah masuk group di atas tidak dihitung lagi di group ini.`;
                                }
                                return `Contoh: tanpa minimum → selalu gunakan benefit bawah (${belowLabel})`;
                            })()}
                        </p>
                    </div>
                ))}

                <div className="m-4">
                    <button type="button" className="btn btn-outline-primary btn-sm" onClick={addGroup}>
                        Tambah Group
                    </button>
                </div>
            </div>
        </div>
    );
};
