"use client";

import {useState, useRef, useEffect } from "react";
import { LoadingSpinner } from "@components/common/LoadingSpinner";
import CheckoutShippingMethodLoading from "./CheckoutShippingMethodLoading";
import { useForm, FormProvider } from "react-hook-form";
import { 
    ShipAddressFormData,
    FullAddressFormData,
    CreateCheckoutAddressVariables,
    PlaceOrderResult,
    PlaceOrderFunction,
    CreatePaymentInitiateVariables
} from "@/types/checkout/type";
import AddressResultDisplay from "./AddressResultDisplay";
import ShippingAddressCheckout from "./ShippingAddressCheckout";
import BillingAddressCheckout from "./BillingAddressCheckout";
import {ShippingMethodCheckout,RefShippingMethodsHandle} from "./ShippingMethodCheckout";
import { useCustomToast } from "@/utils/hooks/useToast";
import {useCheckoutAddress} from "@/utils/hooks/useCheckoutAddress"
import {useCheckoutPaymentMethod} from  "@/utils/hooks/useCheckoutPaymentMethod";
import {useCheckoutShippingMethod} from  "@/utils/hooks/useCheckoutShippingMethod";
import { useAppDispatch } from "@/store/hooks";
import { updateCart } from "@/store/slices/cart-slice";
import {PaymentMethodCheckout,RefPaymentMethodsHandle} from "./PaymentMethodCheckout";
import LoadingPaymentMethod from "./LoadingPaymentMethod";
import LoadingCheckoutPlaceOrder from "./LoadingCheckoutPlaceOrder";
import CheckoutPlaceOrder from "./CheckoutPlaceOrder";
import CommonModal from "@/components/theme/ui/CommonModal";
import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
import { formatCartDetail, shippingAddressToCartAddress, billingAddressToCartAddress } from "@/utils/cartDetailTools";
import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
import { CartDetail,CartAddress } from "@/types/cart/type";
import {normalizePhoneForForm} from "@/utils/phoneNumberTools";
import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
import { clearCart } from "@/store/slices/cart-slice";
import PaypalApplepayButton from "./PaymentButton/PaypalApplepayButton";
import {usePaymentSDKContext} from "@/providers/PaymentSDKProvider";
/***
 * 不用useForShipping字段了
 * 以shipping address 为准，根据shippingaddress 设置billing address
 * 保存完地址之后要重新获取运输方式和支付方式
 * 变更运输方式后重新获取支付方式
 * @todo 购物车为空 跳转到空购物车页面
 */

/**
 * 地址表单默认值
 */
function getBillingAddressFormData(billingAddress:CartAddress) {
    const billingCountry = billingAddress.country || 'US';
    const billingPhoneNumber =  normalizePhoneForForm(billingAddress.phone, billingCountry) || "";
    const res = {
        "billingAddressId": billingAddress.id,
        "billingEmail": billingAddress.email,
        "billingFirstName": billingAddress.firstName,
        "billingLastName": billingAddress.lastName,
        "billingCompanyName": "",
        "billingAddress": billingAddress.address,
        "billingCountry": billingCountry,
        "billingState": billingAddress.state,
        "billingCity": billingAddress.city,
        "billingPostcode": billingAddress.postcode,
        "billingPhoneNumber": billingPhoneNumber,
    };

    return res;
}
function getShippingAddressFormData(shippingAddress:CartAddress) {
    const shippingCountry = shippingAddress.country || 'US';
    const shippingPhoneNumber =  normalizePhoneForForm(shippingAddress.phone, shippingCountry) || "";
    const res = {
        "shippingAddressId": shippingAddress.id,
        "shippingEmail": shippingAddress.email,
        "shippingFirstName": shippingAddress.firstName,
        "shippingLastName": shippingAddress.lastName,
        "shippingCompanyName": "",
        "shippingAddress": shippingAddress.address,
        "shippingCountry": shippingCountry,
        "shippingState": shippingAddress.state,
        "shippingCity": shippingAddress.city,
        "shippingPostcode": shippingAddress.postcode,
        "shippingPhoneNumber": shippingPhoneNumber,
    };

    return res;
}
function getAddressFormDataFromCart(cartDetail:CartDetail, loginEmail?: string) {
    const shippingAddress = cartDetail.shippingAddress;
    const billingAddress = cartDetail.billingAddress;
    const defaultValues = {
        "shippingAddressId": "",
        "shippingEmail": loginEmail ?? '',
        "shippingFirstName": "",
        "shippingLastName": "",
        "shippingCompanyName": "",
        "shippingAddress": "",
        "shippingCountry": "US",
        "shippingState": "",
        "shippingCity": "",
        "shippingPostcode": "",
        "shippingPhoneNumber": "",
        "billingAddressId": "",
        "billingEmail": loginEmail ?? '',
        "billingFirstName": "",
        "billingLastName": "",
        "billingCompanyName": "",
        "billingAddress": "",
        "billingCountry": "US",
        "billingState": "",
        "billingCity": "",
        "billingPostcode": "",
        "billingPhoneNumber": "",
        "billingSameAsShipping": true
    }
    if(billingAddress) {
        const bs = getBillingAddressFormData(billingAddress);
        defaultValues.billingAddressId = bs.billingAddressId;
        defaultValues.billingEmail = bs.billingEmail;
        defaultValues.billingFirstName = bs.billingFirstName;
        defaultValues.billingLastName = bs.billingLastName;
        defaultValues.billingCompanyName = bs.billingCompanyName;
        defaultValues.billingAddress = bs.billingAddress;
        defaultValues.billingCountry = bs.billingCountry;
        defaultValues.billingState = bs.billingState;
        defaultValues.billingCity = bs.billingCity;
        defaultValues.billingPostcode = bs.billingPostcode;
        defaultValues.billingPhoneNumber = bs.billingPhoneNumber;
        // defaultValues.billingSameAsShipping = true;
    }
    if(shippingAddress) {
        const ss = getShippingAddressFormData(shippingAddress);
        defaultValues.shippingAddressId = ss.shippingAddressId;
        defaultValues.shippingEmail = ss.shippingEmail;
        defaultValues.shippingFirstName = ss.shippingFirstName;
        defaultValues.shippingLastName = ss.shippingLastName;
        defaultValues.shippingCompanyName = ss.shippingCompanyName;
        defaultValues.shippingAddress = ss.shippingAddress;
        defaultValues.shippingCountry = ss.shippingCountry;
        defaultValues.shippingState = ss.shippingState;
        defaultValues.shippingCity = ss.shippingCity;
        defaultValues.shippingPostcode = ss.shippingPostcode;
        defaultValues.shippingPhoneNumber = ss.shippingPhoneNumber;
    }
    if( defaultValues.billingEmail === defaultValues.shippingEmail &&
        defaultValues.billingFirstName === defaultValues.shippingFirstName &&
        defaultValues.billingLastName === defaultValues.shippingLastName &&
        defaultValues.billingCompanyName === defaultValues.shippingCompanyName &&
        defaultValues.billingAddress === defaultValues.shippingAddress &&
        defaultValues.billingCountry === defaultValues.shippingCountry &&
        defaultValues.billingState === defaultValues.shippingState &&
        defaultValues.billingCity === defaultValues.shippingCity &&
        defaultValues.billingPostcode === defaultValues.shippingPostcode &&
        defaultValues.billingPhoneNumber === defaultValues.shippingPhoneNumber
    ) {
        defaultValues.billingSameAsShipping = true;
    }
    return defaultValues;
}
/**
 * 生成createCheckoutAddress接口的参数
 */
function generateSaveCheckoutAddressParam(formData: FullAddressFormData):CreateCheckoutAddressVariables {
    const formDataShippingAddress:ShipAddressFormData = {
        shippingAddressId: formData.shippingAddressId,
        shippingEmail: formData.shippingEmail,
        shippingFirstName: formData.shippingFirstName,
        shippingLastName: formData.shippingLastName,
        shippingCompanyName: formData.shippingCompanyName,
        shippingAddress: formData.shippingAddress,
        shippingCountry: formData.shippingCountry,
        shippingState: formData.shippingState,
        shippingCity: formData.shippingCity,
        shippingPostcode: formData.shippingPostcode,
        shippingPhoneNumber: formData.shippingPhoneNumber,
    };
    let formDataBillingAddress = {
        billingAddressId: formData.billingAddressId,
        billingEmail: formData.billingEmail,
        billingFirstName: formData.billingFirstName,
        billingLastName: formData.billingLastName,
        billingCompanyName : formData.billingCompanyName,
        billingAddress: formData.billingAddress,
        billingCountry: formData.billingCountry,
        billingState: formData.billingState,
        billingCity: formData.billingCity,
        billingPostcode: formData.billingPostcode,
        billingPhoneNumber: formData.billingPhoneNumber,

        useForShipping: false,
    };
    if(formData.billingSameAsShipping) {
        formDataBillingAddress = {
            billingAddressId: formData.billingAddressId,
            billingEmail: formDataShippingAddress.shippingEmail,
            billingFirstName: formDataShippingAddress.shippingFirstName,
            billingLastName: formDataShippingAddress.shippingLastName,
            billingCompanyName : formDataShippingAddress.shippingCompanyName,
            billingAddress: formDataShippingAddress.shippingAddress,
            billingCountry: formDataShippingAddress.shippingCountry,
            billingState: formDataShippingAddress.shippingState,
            billingCity: formDataShippingAddress.shippingCity,
            billingPostcode: formDataShippingAddress.shippingPostcode,
            billingPhoneNumber: formDataShippingAddress.shippingPhoneNumber,
            useForShipping: true,
        }
    }
    return {
       ...formDataShippingAddress,
       ...formDataBillingAddress
    };
    
}

export default function CheckoutWrapper({
    loginEmail,
    cartDetailData,
}: {
    loginEmail: string;
    cartDetailData: CartDetail;
}) {

    const {loadSdk} = usePaymentSDKContext();

    const { createOrder } = usePlaceOrder(); 
    const addressFormDefaultValues = getAddressFormDataFromCart(cartDetailData,loginEmail);
    const dispatch = useAppDispatch();
    
    const [cartData, setCartData] = useState<CartDetail>(cartDetailData);
    const {saveCheckoutCart} = useSaveCheckoutCart();
    
    const {
        data: shippingMethodDatas,
        loading: shippingMethodLoading,
        error: shippingMethodError,
        getShippingMethod,
    } = useCheckoutShippingMethod();


    const selectedPaymentMethod = cartData.paymentMethod || 'paypal_smart_button';
    const selectedShippingRate = cartData.selectedShippingRate;
   
    const { 
        data: paymentMethodDatas,
        loading: paymentMethodLoading,
        error: paymentMethodError,
        getPaymentMethod, 
    } = useCheckoutPaymentMethod();

    const { showToast } = useCustomToast();
    const { getCheckoutAddress, saveCheckoutAddress } = useCheckoutAddress(loginEmail);

    const methodShiippingRef = useRef<RefShippingMethodsHandle>(null);
    const methodPaymentRef = useRef<RefPaymentMethodsHandle>(null);

    

    // useForm() 只会在组件初始化时读取一次 defaultValues
    const addressForm = useForm<FullAddressFormData>({
        mode: "onChange",          // 或 "onChange"
        reValidateMode: "onChange",
        defaultValues: addressFormDefaultValues 
    });

    const [addressModalOpen, setAddressModalOpen] = useState(false);


    const [addressSaving, setAddressSaving] = useState(false); // 保存地址时的loading状态

    const changePaymentMethodToloadSdk = (method:string) => {
        if(method === 'klarna' || 
            method === 'afterpay' || 
            method === 'clearpay' || 
            method === 'applepay'
        ) {
            loadSdk(method);
        }
    };

    useEffect(() => {
        changePaymentMethodToloadSdk(selectedPaymentMethod);
    }, [selectedPaymentMethod]);

    const openAddressModal = () => {
        setAddressModalOpen(true);

        if(cartData.billingAddress && cartData.shippingAddress) {
            addressForm.reset({
                ...getAddressFormDataFromCart(cartData)
            });
        }

        
    };
    const closeAddressModal = (e:boolean) => {
        setAddressModalOpen(e);
        // 重置表单
        addressForm.reset();
    };
    const addressFormOnSubmit = async (formData: FullAddressFormData) => { 
        // console.log('addressFormOnSubmit ---- ',formData); return;
        if(addressSaving) {
            return;
        }
        const saveAddressParam = generateSaveCheckoutAddressParam(formData);
        setAddressSaving(true);
        try {

            const res = await saveCheckoutAddress(saveAddressParam);
            console.log('CREATE_CHECKOUT_ADDRESS res ====== ',res);
            // 地址保存成功后重新获取运输方式和支付方式 
            await getShippingMethod();
            await getPaymentMethod();
            
            // 保存完地址之后还要重新请求地址，把保存后的地址id同步到表单里；
            const queryAddressRes = await getCheckoutAddress();
            if(queryAddressRes !== null) {
                addressForm.resetField('shippingAddressId',{
                    defaultValue: queryAddressRes.shippingAddress.shippingAddressId
                });
                addressForm.resetField('billingAddressId',{
                    defaultValue: queryAddressRes.billingAddress.billingAddressId
                });

      
                // 同步地址到购物车详情
                const newBillingAddress = billingAddressToCartAddress(queryAddressRes.billingAddress);
                const newShippingAddress = shippingAddressToCartAddress(queryAddressRes.shippingAddress);
                dispatch(updateCart({
                    billingAddress: newBillingAddress,
                    shippingAddress: newShippingAddress
                }));
                setCartData(Object.assign({...cartData},{
                    billingAddress: {...newBillingAddress},
                    shippingAddress: {...newShippingAddress}
                }));

            }
            setAddressModalOpen(false);
        } catch(err) {
            // 错误处理
            console.error("save address error", err);
           
            showToast('Save address failed. Please try again.', 'danger');
        } finally {
            setAddressSaving(false);
        }
        
    };


    const handlePaymentMethodChange =  async (method: string) => { 
        changePaymentMethodToloadSdk(method);
        let shippingMethod = '-1';
        if(methodShiippingRef.current) {
            shippingMethod = methodShiippingRef.current.getSelectShipMethod();
        }
        overlayLoading.start();
        const saveRes = await saveCheckoutCart({ 
            shippingMethod: shippingMethod,
            paymentMethod: method,
            couponCode: '-1'
        });
        overlayLoading.stop();
        if(!saveRes.error) {
            if(saveRes.data) {
                const newCartDetail = formatCartDetail(saveRes.data);
                dispatch(updateCart(newCartDetail));
                setCartData({...newCartDetail});
            }
            return true;
        } else {
            showToast(saveRes.msg, 'danger');
            return false;
        }

    };
    const handleShippingMethodChange =  async (method: string) => { 
        overlayLoading.start();
        const saveRes = await saveCheckoutCart({ 
            shippingMethod: method,
            paymentMethod: '-1',
            couponCode: '-1'
        });
        overlayLoading.stop();
        if(!saveRes.error) {
            if(saveRes.data) {
                const newCartDetail = formatCartDetail(saveRes.data);
                dispatch(updateCart(newCartDetail));
                setCartData({...newCartDetail});
            }
            // 保存成功之后需要重新获取支付方式
            getPaymentMethod();
        } else {
            showToast(saveRes.msg, 'danger');
        }

    };


    // 校验地址 运输方式，支付方式；
    const validateCheckout = async () => { 
        const addressValid = await addressForm.trigger();

        if(!addressValid) {
            showToast('Please fill in the address information correctly.', 'danger');
            return false;
        }
        if(methodShiippingRef.current) {
            const shippingMethodValid = await methodShiippingRef.current.validateShipMethod();
            if(!shippingMethodValid) {
                showToast('Please select a shipping method.', 'danger');
                return false;
            }
        } else {
            showToast('Please wait for shipping method loading.', 'danger');
            return false;
        }

        if(methodPaymentRef.current) {
            const paymentMethodValid = await methodPaymentRef.current.validatePaymentMethod();
            const paymentMethod = methodPaymentRef.current.getSelectPaymentMethod();
            if(!paymentMethodValid) {
                showToast('Please select a payment method.', 'danger');
                return false;
            }
            if(paymentMethod === 'airwallex') {
                const paymentMethodValid = methodPaymentRef.current.validateAirwallexCard();
                return paymentMethodValid;
            }

        } else {
            showToast('Please wait for payment method loading.', 'danger');
            return false;
        }
        if(!cartData) {
            showToast('Please add product to your cart.', 'danger');
            return false;
        }
        
        //如果购物车详情没有保存过支付方式，则需要保存支付方式
        if(cartData.paymentMethod === null) {
            const pmethod = methodPaymentRef.current.getSelectPaymentMethod();
            const saveRes = await saveCheckoutCart({ 
                shippingMethod: '-1',
                paymentMethod: pmethod,
                couponCode: '-1'
            });
            if(!saveRes.error) {
                if(saveRes.data) {
                    const newCartDetail = formatCartDetail(saveRes.data);
                    dispatch(updateCart(newCartDetail));
                    setCartData({...newCartDetail});
                }
            }
        }

        return true;

    };
    // 苹果支付下单
    const applepayPlaceOrder = async () => { 
        const res = await createOrder();
        if(!res.error) {
            //创建订单成功后清空redux 购物车
            dispatch(clearCart());  
            return {
                orderId: res.data?.gatewayOrderId ?? '',
                webOrderId: res.data?.orderId ?? ''
            };
        } else{
            // 抛出错误让第三方支付能够捕获
            throw new Error("CREATE_ORDER_ERROR: " + res.msg);
        } 
    };
    // 下单
    const handlePlaceOrder: PlaceOrderFunction = async <T,>(params?: CreatePaymentInitiateVariables): Promise<PlaceOrderResult<T>>  => { 
        // 校验地址
        // overlayLoading.start();
        // const validRes = await validateCheckout();
        // if(validRes) {
            const res = await createOrder(params);
            if(res.error) {
                overlayLoading.stop();
                confirmDialog({
                    title: "Warning",
                    content: res.msg + " Create order failed. Please try again.",
                    noCancel: true,
                }).then(() => {});
            } else {
                //创建订单成功后清空redux 购物车
                dispatch(clearCart());  
            }
            const pmethod = methodPaymentRef.current?.getSelectPaymentMethod();
            let resultData: PlaceOrderResult<T>;
            if(pmethod === 'airwallex' && methodPaymentRef.current) {
                const airwallexCardElements = methodPaymentRef.current.getAirwallexCardElements();
                const airCardNumber = airwallexCardElements.cardNumber as T;
                resultData = {
                    data: res.data, 
                    otherData: airCardNumber
                };
            } else if(pmethod === 'klarna') {
                const klaData = {
                    billingAddress: cartData.billingAddress,
                    shippingAddress: cartData.shippingAddress
                } as T;
                resultData = {
                    data: res.data, 
                    otherData: klaData
                };
            } else {
                resultData = {
                    data: res.data, 
                    otherData: null
                };
            }
            return resultData;
        // } else {
        //     overlayLoading.stop();
        //     return {valid: false, data: null, otherData: null};
        // }
    }


    // function tt() {
    //     const arr = [
    //         ['US','3803800217'], 
    //         ['CH','+4186043315'], 
    //         ['US','334-208-6177'], 
    //         ['AU','+61 404103617'], 
    //         ['US','1-9166705105'], 
    //         ['CA','819 384 3221'],
    //         ['US','(409) 239-9482'],
    //         ['US','1-(651) 421-2762'],
    //         ['CH', '1-792930242'],
    //         ['US', '+1 4570438892'],
    //         ['US', '1-+1 (404) 276-1068'],
    //         ['CH', '+49 015164340021'], // 国家与phonecode不一致情况
    //     ];
    //     arr.forEach((item) => {
    //         normalizePhoneForForm(item[1], item[0]);
    //     });
    // }
    return (
        <section className="w-full">
            <div>
            {/* <button className="w-25 h-8 bg-amber-500 flex items-center justify-center" onClick={tt}>test</button> */}
                    {/* {loadingAddress ? 
                        <AddressResultDisplayLoading /> 
                    :
                        <AddressResultDisplay shippingAddress={cartData.shippingAddress || null} 
                            onAddressModalOpenClick={openAddressModal}
                        />
                    } */}
                    <AddressResultDisplay shippingAddress={cartData.shippingAddress || null} 
                        onAddressModalOpenClick={openAddressModal}
                    />
                    <CommonModal
                        isOpen={addressModalOpen}
                        onClose={closeAddressModal}
                        header={
                            <div className="w-full box-border p-3.75 h-14.5 flex justify-between items-center">
                                <span>Shipping Address</span>
                                <button className="w-6 h-6" onClick={() => closeAddressModal(false)}>
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" className="h-6 transition-all ease-in-out hover:scale-110"><path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12"></path></svg>
                                </button>
                            </div>
                        }
                        body={
                            <div className="box-border w-full h-full p-3.75">
                                <p className="text-ly-12 leading-ly-20">
                                    Select a billing address from your address book or enter a new address.
                                </p>
                                <div>
                                    <FormProvider {...addressForm}>
                                        <form>
                                            <ShippingAddressCheckout />
                                            <BillingAddressCheckout />
                                        </form>
                                    </FormProvider>
                                </div>
                            </div>
                        }
                        footer={
                            <div className="box-border w-full p-3.75">
                            <button className="block flex justify-center items-center w-full h-12 bg-ly-green rounded-3xl text-white text-ly-16 font-bold"
                                onClick={addressForm.handleSubmit(addressFormOnSubmit)}
                            >
                                {addressSaving ? <LoadingSpinner /> : 'Save'}
                            </button>
                            </div>
                        }
                    />
            </div>
            <div className="mt-6 box-border px-4">
                <h3 className="text-ly-24 font-medium">Shipping Method</h3>
                {shippingMethodLoading ?
                
                    <CheckoutShippingMethodLoading /> 
                :
                    <ShippingMethodCheckout 
                        ref={methodShiippingRef}  
                        shipMethods={shippingMethodDatas}
                        errorMsg={shippingMethodError}  
                        selectedShippingRate={selectedShippingRate}
                        onShipMethodChange={handleShippingMethodChange}  
                    />
                }

            </div>

            <div className="mt-6 box-border px-4">
                <h3 className="text-ly-24 font-medium">Payment Method</h3>
                { paymentMethodLoading && <LoadingPaymentMethod /> }
                { (!paymentMethodLoading && paymentMethodError) && <p className="mt-3 text-red-500 text-ly-12">{paymentMethodError}</p>}
                { (!paymentMethodLoading && !paymentMethodError) && 
                    <PaymentMethodCheckout 
                        ref={methodPaymentRef}
                        paymentMethods={paymentMethodDatas} 
                        selectedPaymentMethod={selectedPaymentMethod}
                        onPaymentMethodChange={handlePaymentMethodChange}
                    />
                }
                
            </div>
            <div className="mt-3 box-border px-4 pb-8">
                <p className="text-ly-12 text-[#666666] leading-ly-20">By providing your information, you agree to Wiggins'sPrivacy Policyand Terms of Use.</p>
                <div className="mt-6 w-full">
                    { paymentMethodLoading ?
                        <LoadingCheckoutPlaceOrder />
                    :
                        (selectedPaymentMethod === 'applepay' ?
                        <PaypalApplepayButton 
                            grandTotal={cartData.grandTotal}
                            billingContact={cartData.billingAddress}
                            shippingContact={cartData.shippingAddress}
                            validateCheckout={validateCheckout}
                            createOrder={applepayPlaceOrder}
                        />
                        :
                        <CheckoutPlaceOrder 
                            paymentMethod={selectedPaymentMethod}
                            validateCheckout={validateCheckout}
                            clickPlaceOrder={handlePlaceOrder}
                        />)
                        
                    }
                </div>
            </div>

        </section> 
        
    );
};
