"use client";

import {useMemo,useEffect, useState} from "react";
import { useQuery } from "@apollo/client/react";
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_FULL_PHONE, IS_VALID_PHONECODE } 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 ShippingAddressCheckout () {
    const {countries} = useConfig();
    const { 
        getValues,
        setValue,
        register,
        formState: { errors },
        control 
    } = useFormContext() // retrieve all hook methods

    const countriesOptions = useMemo(() => {
        return countries.map((country) => ({
            value: country.code,
            label: country.name,
            id: String(country._id),
        }))
    },[countries]);

    const selectedCountryCode = useWatch({
        control,
        name: 'shippingCountry',
    });
    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);

    // 国家变更后 state字段的值需要清空
    // 选择国家时同步电话区号
    useEffect(() => {
        const preShippingPhoneNum = getValues('shippingPhoneNumber');
        const regPhoneCode = IS_VALID_PHONECODE;
    
        if(preShippingPhoneNum && !hasUserSelectedPhoneCode) {
            const newPhoneCode = getPhoneCodeBycountryCode(selectedCountryCode);
            const codePart = regPhoneCode.exec(preShippingPhoneNum);
            let phone = preShippingPhoneNum;
            if(codePart) {
                phone = preShippingPhoneNum.replace(codePart[0], '');
            }
            if(codePart && newPhoneCode !== codePart[0].trim()) {
                return;
            }
            setValue('shippingPhoneNumber',formatFinalPhoneValue(newPhoneCode, phone))
        }
        
    },[selectedCountryCode,hasUserSelectedPhoneCode,getValues,setValue]);


    return (
        <div className="box-border w-full">
            <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("shippingEmail", {
                        required: "Email is required",
                        pattern: {
                            value: EMAIL_REGEX,
                            message: "Please enter a valid email address",
                        }
                    })}
                    error={errors.shippingEmail && errors.shippingEmail.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("shippingFirstName", {
                                required: "First name is required",
                                pattern: {
                                    value: IS_VALID_INPUT,
                                    message: "Invalid First Name",
                                }
                            })}
                            error={errors.shippingFirstName && errors.shippingFirstName.message as string}
                        />
                    </div> 
                    <div className="w-41.25 flex-none">
                        <InputText
                            type="text"
                            placeholder="Last name"
                            {...register("shippingLastName", {
                                required: "Last name is required",
                                pattern: {
                                    value: IS_VALID_INPUT,
                                    message: "Invalid Last Name",
                                }
                            })}
                            error={errors.shippingLastName && errors.shippingLastName.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("shippingAddress", {
                        required: "Address is required",
                    })}
                    error={errors.shippingAddress && errors.shippingAddress.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("shippingCountry", {
                                    required: "Country/Region field is required",
                                    onChange: () => {
                                        // 清空 state/city
                                        setValue('shippingState','',{
                                            shouldDirty: true,
                                            shouldValidate: true,
                                        });
                                        setValue('shippingCity','',{
                                            shouldDirty: true,
                                            shouldValidate: true,
                                        });
                                    }
                                })}
                                options={countriesOptions}
                                error={errors.shippingCountry && errors.shippingCountry.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("shippingState", {
                                        required: "State/Province field is required"
                                    })}
                                    options={statesOptions}
                                    error={errors.shippingState && errors.shippingState.message as string}
                                />
                            )
                            : (
                                <InputText
                                    type="text"
                                    placeholder="State/Province"
                                    {...register("shippingState", {
                                        required: "State/Province field is required"
                                    })}
                                    error={errors.shippingState && errors.shippingState.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("shippingPostcode", {
                                    required: "Postcode field is required",
                                    pattern: {
                                        value: IS_VALID_INPUT,
                                        message: "Invalid Postcode",
                                    },
                                })}
                                error={errors.shippingPostcode&& errors.shippingPostcode.message as string}
                            />
                        </div>
                        <div className="w-41.25 flex-none">
                            <InputText
                                type="text"
                                placeholder="City"
                                {...register("shippingCity", {
                                    required: "City field is required",
                                    pattern: {
                                        value: IS_VALID_INPUT,
                                        message: "Invalid City",
                                    },
                                })}
                                error={errors.shippingCity && errors.shippingCity.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="shippingPhoneNumber"
                    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>
    );
};
