"use client";

import { useMemo, useState, useEffect } from "react";
import { useQuery } from "@apollo/client/react";
import clsx from "clsx";
import { 
    useFormContext, 
    useWatch,
    Controller 
} from "react-hook-form";
import {
    formatFinalPhoneValue,
    getPhoneCodeBycountryCode
} from "@/components/theme/ui/PhoneNumberInput/phoneCodeMetaData";
import { GET_COUNTRY_STATES } from "@/graphql";
import { 
    EMAIL_REGEX, 
    IS_VALID_INPUT, 
    IS_VALID_PHONECODE,
    IS_VALID_FULL_PHONE 
} from "@utils/constants";
import InputText from "@/components/theme/ui/InputText";
import Select from "@/components/theme/ui/Select";
import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumberInput";
import { LoadingSpinner } from "@components/common/LoadingSpinner";
import { useConfig } from "@utils/hooks/useConfig";
export default function BillingAddressCheckout () {
    const {countries} = useConfig();
    const { 
        getValues,
        setValue,
        register,
        formState: { errors },
        control 
    } = useFormContext() // retrieve all hook methods

    const billingSameAsShipping = useWatch({
        control,
        name: 'billingSameAsShipping',
    });

    const shippingFields = useWatch({
        control,
        name: [
            "shippingEmail",
            "shippingFirstName",
            "shippingLastName",
            "shippingCompanyName",
            "shippingAddress",
            "shippingCountry",
            "shippingState",
            "shippingCity",
            "shippingPostcode",
            "shippingPhoneNumber",
        ],
    });
    useEffect(() => {
        if (!billingSameAsShipping) return;

        const [
            shippingEmail,
            shippingFirstName,
            shippingLastName,
            shippingCompanyName,
            shippingAddress,
            shippingCountry,
            shippingState,
            shippingCity,
            shippingPostcode,
            shippingPhoneNumber,
        ] = shippingFields;

        setValue("billingEmail", shippingEmail);
        setValue("billingFirstName", shippingFirstName);
        setValue("billingLastName", shippingLastName);
        setValue("billingCompanyName", shippingCompanyName);
        setValue("billingAddress", shippingAddress);
        setValue("billingCountry", shippingCountry);
        setValue("billingState", shippingState);
        setValue("billingCity", shippingCity);
        setValue("billingPostcode", shippingPostcode);
        setValue("billingPhoneNumber", shippingPhoneNumber);
    }, [billingSameAsShipping, shippingFields, setValue]);
    
    const countriesOptions = useMemo(() => {
        return countries.map((country) => ({
            value: country.code,
            label: country.name,
            id: String(country._id),
        }))
    },[countries]);

    const selectedCountryCode = useWatch({
        control,
        name: 'billingCountry',
    });

    const selectedCountry = useMemo(() => {
        return countries.find( (country) => country.code === selectedCountryCode)
    }, [countries, selectedCountryCode]);

    const { data: statesData, loading: statesLoading } = useQuery(GET_COUNTRY_STATES, {
        variables: {
            countryId: selectedCountry?._id
        },

        skip: !selectedCountryCode,
    });

    let statesOptions: { value: string; label: string, id: string }[] = [];
    if(statesData) {
        statesOptions = statesData.countryStates.map((state) => ({
            value: state.code,
            label: state.defaultName,
            id: String(state._id),
        }));
    }

   
    // 是否用户手动选择过区号
    const [hasUserSelectedPhoneCode, setHasUserSelectedPhoneCode] = useState(false);

    // 选择国家时同步电话区号
    useEffect(() => {
        const preBillingPhoneNum = getValues('billingPhoneNumber');
        const regPhoneCode = IS_VALID_PHONECODE;
    
        if(preBillingPhoneNum && !hasUserSelectedPhoneCode) {
            const newPhoneCode = getPhoneCodeBycountryCode(selectedCountryCode);
            const codePart = regPhoneCode.exec(preBillingPhoneNum);
            let phone = preBillingPhoneNum;
            if(codePart) {
                phone = preBillingPhoneNum.replace(codePart[0], '');
            }
             if(codePart && newPhoneCode !== codePart[0].trim()) {
                return;
            }
            setValue('billingPhoneNumber',formatFinalPhoneValue(newPhoneCode, phone))
        }
        
    },[selectedCountryCode,hasUserSelectedPhoneCode,getValues,setValue]);



    
    return (
        <section className="w-full mt-4"> 
            <div className="box-border w-full p-3 bg-ly-lightgray">
                <div className="flex justify-between items-center">
                    <span className="text-ly-12 flex-none">Billing Address</span>
                    <label className="group relative w-9 h-5.5 flex-none">
                        <input className="absolute w-full h-full top-0 left-0 opacity-0 z-10"
                            type="checkbox"
                            {...register("billingSameAsShipping")}
                        />
                        <span className="transition-all box-border block px-0.5 w-full h-full rounded-full flex items-center bg-[#c2c2c2] group-has-[:checked]:bg-[#363636]">
                            <span className="transition-all block w-4.5 h-4.5 rounded-full bg-white group-has-[:checked]:ml-3.5"></span>
                        </span>
                    </label>
                    
                </div>
                <p className="text-ly-12 mt-1.25">Same As Shipping Address</p>
            </div>

            <div className={clsx("box-border w-full mt-4",{
                    "hidden": billingSameAsShipping,
                })}
            >
                <div className="w-full">
                    <label className="text-ly-12 block mb-4 font-semibold">
                        Email *
                    </label>
                    <InputText
                        type="email"
                        placeholder="Enter your email address"
                        {...register("billingEmail", {
                            required: "Email is required",
                            pattern: {
                                value: EMAIL_REGEX,
                                message: "Please enter a valid email address",
                            }
                        })}
                        error={errors.billingEmail && errors.billingEmail.message as string}
                    />
                </div>
                <div className="w-full mt-4">
                    <label className="text-ly-12 block mb-4 font-semibold">
                        Name *
                    </label>
                    <div className="w-full flex justify-between">
                        <div className="w-41.25 flex-none">
                            <InputText
                                type="text"
                                placeholder="First name"
                                {...register("billingFirstName", {
                                    required: "First name is required",
                                    pattern: {
                                        value: IS_VALID_INPUT,
                                        message: "Invalid First Name",
                                    }
                                })}
                                error={errors.billingFirstName && errors.billingFirstName.message as string}
                            />
                        </div> 
                        <div className="w-41.25 flex-none">
                            <InputText
                                type="text"
                                placeholder="Last name"
                                {...register("billingLastName", {
                                    required: "Last name is required",
                                    pattern: {
                                        value: IS_VALID_INPUT,
                                        message: "Invalid Last Name",
                                    }
                                })}
                                error={errors.billingLastName && errors.billingLastName.message as string}
                            />
                        </div>
                    </div>
                </div>
    
                <div className="w-full mt-4">
                    <label className="text-ly-12 block mb-4 font-semibold">Address *</label>
                    <InputText
                        type="text"
                        placeholder="Please Input Your Detailed Address With Apt. No"
                        {...register("billingAddress", {
                            required: "Address is required",
                        })}
                        error={errors.billingAddress && errors.billingAddress.message as string}
                    />
                    
                </div>
    
                <div className="w-full mt-4">
                    <label className="text-ly-12 block mb-4 font-semibold">Country and State/Province  *</label>
                    <div className="w-full">
                        <div className="w-full flex justify-between">
                            <div className="w-41.25 flex-none">
                                <Select placeholder="Country/Region"
                                    {...register("billingCountry", {
                                        required: "Country/Region field is required",
                                        onChange: () => {
                                            setValue('billingState','',{
                                                shouldDirty: true,
                                                shouldValidate: true,
                                            });
                                            setValue('billingCity','',{
                                                shouldDirty: true,
                                                shouldValidate: true,
                                            });
                                        }
                                    })}
                                    options={countriesOptions}
                                    error={errors.billingCountry && errors.billingCountry.message as string}
                                /> 
                            </div>
                            <div className="w-41.25 flex-none relative">
                                {statesLoading && <LoadingSpinner className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" />}
                                {statesOptions.length > 0 ?
                                (
                                    <Select placeholder="State/Province"
                                        {...register("billingState", {
                                            required: "State/Province field is required"
                                        })}
                                        options={statesOptions}
                                        error={errors.billingState && errors.billingState.message as string}
                                    />
                                )
                                : (
                                    <InputText
                                        type="text"
                                        placeholder="State/Province"
                                        {...register("billingState", {
                                            required: "State/Province field is required"
                                        })}
                                        error={errors.billingState && errors.billingState.message as string}
                                    />
                                )}
                                
                            </div>
                            
                        </div>
                        <div className="w-full flex justify-between mt-4">
                            <div className="w-41.25 flex-none">
                                <InputText
                                    type="text"
                                    placeholder="Zip/Postal Code"
                                    {...register("billingPostcode", {
                                        required: "Postcode field is required",
                                        pattern: {
                                            value: IS_VALID_INPUT,
                                            message: "Invalid Postcode",
                                        },
                                    })}
                                    error={errors.billingPostcode&& errors.billingPostcode.message as string}
                                />
                            </div>
                            <div className="w-41.25 flex-none">
                                <InputText
                                    type="text"
                                    placeholder="City"
                                    {...register("billingCity", {
                                        required: "City field is required",
                                        pattern: {
                                            value: IS_VALID_INPUT,
                                            message: "Invalid City",
                                        },
                                    })}
                                    error={errors.billingCity && errors.billingCity.message as string}
                                />
                            </div>
                        </div>
                        
                    </div>
                </div>
    
                <div className="w-full mt-4"> 
                    <label className="text-ly-12 block mb-4 font-semibold">Phone number *</label>
                        <Controller
                        name="billingPhoneNumber"
                        control={control}
                        rules={{
                            required: "Phone Number is required",
                            pattern: {
                                value: IS_VALID_FULL_PHONE,
                                message: "Invalid Phone Number",
                            }
                        }}
                        render={({ field, fieldState }) => {
                            return (
                                <PhoneNumberInput 
                                    placeholder="Please Input Your Phone Number"
                                    value={field.value}
                                    onChange={field.onChange}
                                    onBlur={field.onBlur}
                                    name={field.name}
                                    ref={field.ref}
                                    error={fieldState.error?.message}
                                    countryCode={selectedCountryCode}
                                    hasUserSelectedPhoneCode={hasUserSelectedPhoneCode}
                                    onHasUserSelectedPhoneCode={() => setHasUserSelectedPhoneCode(true)}
                                />
                            );
                        }}
                    />
    
                    
                </div>
    
            </div>


        </section>
    );
}