import { setPageTitle } from '@/store/themeConfigSlice';
import { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import Link from 'next/link';

import { coloredToast } from '@/lib/toast';
import { useRouter } from 'next/router';
import PromotionForm from '@/components/Promotions/Form';
import { createEmptyGroup } from '@/components/Promotions/CategoryRewardForm';
import { SavePromotion } from '@/utils/savePromotion';
import { SaveCategoryReward } from '@/utils/saveCategoryReward';
import { logActivity } from '@/utils/activityLogger';
import Swal from 'sweetalert2';

interface Promotion {
    id?: string;
    promotion_type?: string;
    promotion_name?: string;
    promotion_start?: Date;
    promotion_end?: Date;
    promotion_is_active?: boolean;
    promotion_case?: string[];
    promotion_category?: string;
    promotion_include_categories: string[];
    promotion_exclude_categories: string[];
    promotion_included_products: string[];
    promotion_excluded_products: string[];
    promotion_unique_users: string[];
    promotion_merge_free_items?: boolean;
    promotion_stacking_mode?: string;
    promotion_merch_scope?: string;
    exit_intent_only?: boolean;
    exit_require_login?: boolean;
    promotion_reward_groups?: any[];
    promotion_member_only?: boolean;
}
interface PromotionProps {
    promotionProp: Promotion;
}

const normalizeClassicCases = (cases: any[] = []) =>
    cases.map((item: any) => {
        if (item.case_type === 'free_item') {
            if (Array.isArray(item.promo_value) && item.promo_value.length > 0 && typeof item.promo_value[0] === 'object' && 'productId' in item.promo_value[0]) {
                return item;
            }

            let productIdArray: string[] = [];
            if (typeof item.promo_value === 'string') {
                try {
                    productIdArray = JSON.parse(item.promo_value);
                } catch {
                    productIdArray = item.promo_value
                        .split(',')
                        .map((id: string) => id.trim())
                        .filter((id: string) => id);
                }
            } else if (Array.isArray(item.promo_value)) {
                productIdArray = item.promo_value;
            }

            return {
                ...item,
                promo_value: productIdArray.map((productId: string) => ({
                    productId,
                    active: true,
                })),
            };
        }
        return item;
    });

const EditPromotion: React.FC<PromotionProps> = ({ promotionProp }) => {
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch(setPageTitle('Promotion Edit'));
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    const [isMounted, setIsMounted] = useState(false);
    const [initialPromotion, setInitialPromotion] = useState<Promotion | null>(null);
    const [isUpdate, setIsUpdate] = useState(true);

    const router = useRouter();

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

    useEffect(() => {
        if (isUpdate) {
            setInitialPromotion(JSON.parse(JSON.stringify(promotionProp)));
        }
    }, [isUpdate, promotionProp]);

    const [promotion, setPromotion] = useState<any>({
        id: promotionProp.id || (promotionProp as any)._id,
        promotion_type: promotionProp.promotion_type || '',
        promotion_name: promotionProp.promotion_name,
        promotion_start: promotionProp.promotion_start,
        promotion_end: promotionProp.promotion_end,
        promotion_is_active: promotionProp.promotion_is_active,
        promotion_case: normalizeClassicCases(promotionProp.promotion_case || []),
        promotion_category: promotionProp.promotion_category || '',
        promotion_include_categories: promotionProp.promotion_include_categories || [],
        promotion_exclude_categories: promotionProp.promotion_exclude_categories || [],
        promotion_included_products: promotionProp.promotion_included_products || [],
        promotion_excluded_products: promotionProp.promotion_excluded_products || [],
        promotion_unique_users: promotionProp.promotion_unique_users || [],
        promotion_merge_free_items: promotionProp.promotion_merge_free_items ?? true,
        promotion_stacking_mode: promotionProp.promotion_stacking_mode || 'prefer_discount',
        promotion_merch_scope: promotionProp.promotion_merch_scope || 'per_order',
        exit_intent_only: Boolean(promotionProp.exit_intent_only),
        exit_require_login: Boolean(promotionProp.exit_require_login),
        promotion_reward_groups:
            Array.isArray(promotionProp.promotion_reward_groups) && promotionProp.promotion_reward_groups.length
                ? promotionProp.promotion_reward_groups
                : [createEmptyGroup()],
        promotion_member_only: (() => {
            if (typeof promotionProp.promotion_member_only === 'boolean') {
                return promotionProp.promotion_member_only;
            }
            const roles = Array.isArray((promotionProp as any).promotion_user_roles)
                ? (promotionProp as any).promotion_user_roles.map((role: string) => String(role || '').toLowerCase())
                : [];
            return roles.includes('member') && !roles.includes('universal');
        })(),
    });
    const [isLoading, setIsLoading] = useState(false);

    const isMultiProduct = promotion.promotion_type === 'category_reward';

    const labelMap: Partial<Record<keyof Promotion, string>> = {
        promotion_name: 'Promotion Name',
        promotion_type: 'Promotion Type',
        promotion_start: 'Promotion Start',
        promotion_end: 'Promotion End',
        promotion_is_active: 'Promotion Active',
        promotion_case: 'Promotion Case',
        promotion_category: 'Promotion Category',
        promotion_include_categories: 'Promotion Include Categories',
        promotion_exclude_categories: 'Promotion Exclude Categories',
        promotion_included_products: 'Promotion Included Products',
        promotion_excluded_products: 'Promotion Excluded Products',
        promotion_unique_users: 'Promotion Unique Users',
        promotion_stacking_mode: 'Stacking Mode',
        promotion_merch_scope: 'Merch Scope',
        exit_intent_only: 'Trigger on Back Page',
        exit_require_login: 'Wajib Login / Daftar',
        promotion_reward_groups: 'Reward Groups',
        promotion_member_only: 'Member Only',
    };

    const getPromotionChangesDescription = () => {
        if (!initialPromotion) return 'No previous data to compare.';

        const updatedFields: string[] = [];

        (Object.keys(promotion) as (keyof Promotion)[]).forEach((key) => {
            const oldValue = initialPromotion[key];
            const newValue = promotion[key];

            if (Array.isArray(oldValue) && Array.isArray(newValue)) {
                if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) {
                    updatedFields.push(`${labelMap[key] || key}: [Changed]`);
                }
            } else if (typeof oldValue === 'boolean' || typeof newValue === 'boolean') {
                if (oldValue !== newValue) {
                    updatedFields.push(`${key}: ${oldValue ? 'Yes' : 'No'} -> ${newValue ? 'Yes' : 'No'}`);
                }
            } else if (oldValue instanceof Date && newValue instanceof Date) {
                if (oldValue.getTime() !== newValue.getTime()) {
                    updatedFields.push(`${key}: ${oldValue.toISOString()} -> ${newValue.toISOString()}`);
                }
            } else if (oldValue !== newValue) {
                const label = labelMap[key] || key;
                updatedFields.push(`${label}: ${oldValue} -> ${newValue}`);
            }
        });

        return updatedFields.length > 0 ? updatedFields.join(' | ') : 'No changes made.';
    };

    const isFormEmpty = () => {
        if (isMultiProduct) {
            return !(promotion.promotion_reward_groups || []).some((g: any) => (g.include_categories || []).length > 0);
        }
        const hasCategories =
            (promotion.promotion_include_categories || []).length > 0 ||
            (promotion.promotion_exclude_categories || []).length > 0 ||
            (promotion.promotion_included_products || []).length > 0 ||
            (promotion.promotion_excluded_products || []).length > 0;

        return !hasCategories;
    };

    const savePromotion = async () => {
        if (isFormEmpty()) {
            const result = await Swal.fire({
                title: 'Form Kosong',
                text: isMultiProduct
                    ? 'Include categories belum diisi. Tetap ingin menyimpan?'
                    : 'Include dan exclude categories/products tidak diisi. Tetap ingin menyimpan?',
                icon: 'warning',
                showCancelButton: true,
                confirmButtonText: 'Ya, tetap simpan',
                cancelButtonText: 'Batal',
                confirmButtonColor: '#3085d6',
                cancelButtonColor: '#d33',
            });

            if (!result.isConfirmed) {
                return;
            }
        }

        setIsLoading(true);

        const validationSave = isMultiProduct
            ? SaveCategoryReward(promotion)
            : SavePromotion({
                  promotion_type: promotion.promotion_type,
                  promotion_name: promotion.promotion_name,
                  promotion_start: promotion.promotion_start,
                  promotion_end: promotion.promotion_end,
                  promotion_is_active: promotion.promotion_is_active,
                  promotion_case: promotion.promotion_case,
                  promotion_category: promotion.promotion_category,
                  promotion_include_categories: promotion.promotion_include_categories,
                  promotion_exclude_categories: promotion.promotion_exclude_categories,
                  promotion_included_products: promotion.promotion_included_products,
                  promotion_excluded_products: promotion.promotion_excluded_products,
                  promotion_unique_users: promotion.promotion_unique_users || [],
                  promotion_merge_free_items: promotion.promotion_merge_free_items ?? true,
                  promotion_member_only: Boolean(promotion.promotion_member_only),
              });

        if (validationSave.status === false) {
            setIsLoading(false);
            return;
        }

        try {
            const api_url = process.env.API_URL;
            const payload = {
                data: validationSave.data,
            };

            const response = await fetch(`${api_url}api/promotions/update/${promotion.id}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(payload),
                credentials: 'include',
            });

            if (!response.ok) {
                const res = await response.json();
                coloredToast('warning', res.message);
                setIsLoading(false);
                return;
            }

            const changes = getPromotionChangesDescription();

            coloredToast('success', `promotion updated successfully`);
            await logActivity({
                location: 'Promotion Page',
                description: `Promotion ${promotion.promotion_name} | Updated: ${changes}`,
            });
            router.push('/promotions');
        } catch (error) {
            console.error(error);
            await logActivity({
                location: 'Promotion Page',
                description: `Promotion ${promotion.promotion_name} | Failed to update`,
            });
            coloredToast('danger', 'something went wrong');
        }

        setIsLoading(false);
    };

    return (
        <>
            {isMounted && (
                <>
                    <div className="mb-3">
                        <ul className="flex space-x-2 rtl:space-x-reverse">
                            <li>
                                <Link href="/promotions" className="text-primary hover:underline">
                                    Promotion
                                </Link>
                            </li>
                            <li className="before:content-['/'] ltr:before:mr-2 rtl:before:ml-2">
                                <span>edit</span>
                            </li>
                        </ul>
                    </div>
                    <div className="flex flex-col gap-2.5 xl:flex-row">
                        <PromotionForm promotion={promotion} setPromotion={setPromotion} isUpdate={isUpdate} />
                    </div>
                    <div className="mt-6 w-full xl:w-80">
                        <div className="panel">
                            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-1">
                                <button type="button" disabled={isLoading} onClick={savePromotion} className="btn btn-success w-full gap-2">
                                    {isLoading ? (
                                        <span className="inline-block h-5 w-5 animate-spin rounded-full border-2 border-white border-l-transparent align-middle ltr:mr-4 rtl:ml-4"></span>
                                    ) : (
                                        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 shrink-0 ltr:mr-2 rtl:ml-2">
                                            <path
                                                d="M3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355C22 19.0711 22 16.714 22 12C22 11.6585 22 11.4878 21.9848 11.3142C21.9142 10.5049 21.586 9.71257 21.0637 9.09034C20.9516 8.95687 20.828 8.83317 20.5806 8.58578L15.4142 3.41944C15.1668 3.17206 15.0431 3.04835 14.9097 2.93631C14.2874 2.414 13.4951 2.08581 12.6858 2.01515C12.5122 2 12.3415 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355Z"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                            />
                                            <path
                                                d="M17 22V21C17 19.1144 17 18.1716 16.4142 17.5858C15.8284 17 14.8856 17 13 17H11C9.11438 17 8.17157 17 7.58579 17.5858C7 18.1716 7 19.1144 7 21V22"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                            />
                                            <path opacity="0.5" d="M7 8H13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
                                        </svg>
                                    )}
                                    Save
                                </button>
                            </div>
                        </div>
                    </div>
                </>
            )}
        </>
    );
};
export default EditPromotion;

export const getServerSideProps = async (context: any) => {
    try {
        const { params } = context;
        const { promotion } = params;
        const api_url = process.env.API_URL;

        const response = await fetch(`${api_url}api/promotions/${promotion}`);

        if (!response.ok) {
            return {
                notFound: true,
            };
        }
        const data = await response.json();
        const promotionProp = {
            ...data,
            id: data.id || data._id,
        };
        return {
            props: {
                promotionProp,
            },
        };
    } catch (err) {
        return {
            notFound: true,
        };
    }
};
