import { coloredToast } from '@/lib/toast';

export type CategoryRewardBenefitType = 'none' | 'voucher' | 'free_item';

export interface CategoryRewardBenefit {
    type: CategoryRewardBenefitType;
    coupon_id?: string;
    products?: { productId: string; active: boolean }[];
    qty_mode?: 'per_transaction' | 'per_qty';
}

export interface CategoryRewardGroup {
    id: string;
    name: string;
    include_categories: string[];
    threshold: number | null;
    /** subtotal | per_item | qty — default subtotal for legacy groups */
    threshold_basis?: 'subtotal' | 'per_item' | 'qty';
    /** above_only | below_only | combine — default above_only */
    rule_combination?: 'above_only' | 'below_only' | 'combine';
    above_benefit: CategoryRewardBenefit;
    below_benefit: CategoryRewardBenefit;
}

export interface CategoryRewardPromotion {
    promotion_type: string;
    promotion_name: string;
    promotion_start: Date | string;
    promotion_end: Date | string;
    promotion_is_active: boolean;
    promotion_stacking_mode: string;
    promotion_merch_scope?: string;
    /** Benefit only after checkout exit intercept */
    exit_intent_only?: boolean;
    /** Guest must login/register before unlock (requires exit_intent_only) */
    exit_require_login?: boolean;
    promotion_member_only?: boolean;
    promotion_reward_groups: CategoryRewardGroup[];
}

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

const normalizeBenefit = (benefit?: CategoryRewardBenefit): CategoryRewardBenefit => {
    const type = benefit?.type;
    if (type === 'voucher') {
        return {
            type: 'voucher',
            coupon_id: benefit?.coupon_id || '',
            products: [],
            qty_mode: 'per_transaction',
        };
    }
    if (type === 'free_item') {
        return {
            type: 'free_item',
            coupon_id: '',
            products: (benefit?.products || []).filter((p) => p?.productId && p.active !== false),
            qty_mode: benefit?.qty_mode === 'per_qty' ? 'per_qty' : 'per_transaction',
        };
    }
    return emptyBenefit();
};

export const SaveCategoryReward = (promotionForm: CategoryRewardPromotion) => {
    const validationError = validateCategoryReward(promotionForm);
    if (validationError) {
        coloredToast('warning', validationError);
        return { status: false };
    }

    const data = {
        promotion_type: 'category_reward',
        promotion_name: promotionForm.promotion_name,
        promotion_start: promotionForm.promotion_start,
        promotion_end: promotionForm.promotion_end,
        promotion_is_active: promotionForm.promotion_is_active,
        promotion_stacking_mode: (() => {
            const raw = promotionForm.promotion_stacking_mode || 'prefer_discount';
            if (raw === 'discount_only') return 'prefer_discount';
            if (raw === 'merch_only') return 'prefer_merch';
            if (['prefer_discount', 'prefer_merch', 'allow_both'].includes(raw)) return raw;
            return 'prefer_discount';
        })(),
        promotion_merch_scope: promotionForm.promotion_merch_scope || 'per_order',
        exit_intent_only: Boolean(promotionForm.exit_intent_only),
        exit_require_login: Boolean(
            promotionForm.exit_intent_only && promotionForm.exit_require_login
        ),
        promotion_member_only: Boolean(promotionForm.promotion_member_only),
        promotion_reward_groups: (promotionForm.promotion_reward_groups || []).map((group, index) => ({
            id: group.id || `group_${index + 1}`,
            name: group.name || `Group ${index + 1}`,
            include_categories: group.include_categories || [],
            threshold:
                group.threshold === null || group.threshold === undefined || String(group.threshold) === ''
                    ? null
                    : Number(group.threshold),
            threshold_basis: ['subtotal', 'per_item', 'qty'].includes(group.threshold_basis || '')
                ? group.threshold_basis
                : 'subtotal',
            rule_combination: ['above_only', 'below_only', 'combine'].includes(group.rule_combination || '')
                ? group.rule_combination
                : 'above_only',
            above_benefit: normalizeBenefit(group.above_benefit),
            below_benefit: normalizeBenefit(group.below_benefit),
        })),
        promotion_case: [],
        promotion_category: '',
        promotion_include_categories: [],
        promotion_exclude_categories: [],
        promotion_included_products: [],
        promotion_excluded_products: [],
    };

    return { status: true, data };
};

const validateBenefit = (label: string, side: 'above' | 'below', benefit?: CategoryRewardBenefit): string | null => {
    const type = benefit?.type || 'none';
    if (!['none', 'voucher', 'free_item'].includes(type)) {
        return `${label}: invalid ${side}_benefit.type.`;
    }
    if (type === 'voucher' && !benefit?.coupon_id) {
        return `${label}: coupon is required for ${side} voucher benefit.`;
    }
    if (type === 'free_item') {
        const products = (benefit?.products || []).filter((p) => p?.productId);
        if (!products.length) return `${label}: free item products are required for ${side} benefit.`;
        if (!['per_transaction', 'per_qty'].includes(benefit?.qty_mode || '')) {
            return `${label}: qty mode is required for ${side} free item.`;
        }
    }
    return null;
};

const validateCategoryReward = (form: CategoryRewardPromotion): string | null => {
    if (!form.promotion_name) return 'Promotion name is required.';
    if (!form.promotion_start || !form.promotion_end) return 'Start and end date are required.';

    const startDate = new Date(form.promotion_start);
    const endDate = new Date(form.promotion_end);
    if (startDate > endDate) return 'Start date is later than end date';

    const groups = form.promotion_reward_groups || [];
    if (!groups.length) return 'Please add at least 1 reward group.';

    for (let i = 0; i < groups.length; i++) {
        const group = groups[i];
        const label = group.name || `Group ${i + 1}`;
        if (!group.include_categories?.length) {
            return `${label}: include categories is required.`;
        }

        const aboveError = validateBenefit(label, 'above', group.above_benefit);
        if (aboveError) return aboveError;
        const belowError = validateBenefit(label, 'below', group.below_benefit);
        if (belowError) return belowError;

        if ((group.above_benefit?.type || 'none') === 'none' && (group.below_benefit?.type || 'none') === 'none') {
            return `${label}: at least one benefit (above or below) is required.`;
        }
    }

    return null;
};
