import { useEffect, useState } from 'react';
import { useForm, Controller } from 'react-hook-form'
import { useDebounce } from 'use-debounce'
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import {
    Button,
    Input,
    PhoneInput,
    Select,
    InputLabel,
    FormControl,
    Typography,
    Autocomplete
} from '@sofaltaeu/sofaltaeu-components'
import { Form, ContainerButton, MenuItem } from './styled'
import { CreateAccount } from '../../../interfaces/services/ICreateUser'
import { PhoneNumberUtil } from 'google-libphonenumber';
const phoneUtil = PhoneNumberUtil.getInstance();

import { useMutation } from 'react-query';
import { getCidades, validarDadosUsuario } from '../../../services';
import { Cidade } from '../../../interfaces/services/ICidades';
const formDadosAdicionaisSchema = z.object({
    sexo: z.string(),
    nascimento: z.string(),
    telefone: z.string().min(5, 'Telefone inválido'),
    cidades_idcidades: z.number({
        required_error: 'Cidade é obrigatória'
    }),
})
type FormDadosAdicionaisSchema = z.infer<typeof formDadosAdicionaisSchema>

interface FormDadosAdicionaisProps {
    nextSetp: ()=>void,
    prevSetp: ()=>void,
    state: CreateAccount
    setState: (payload:CreateAccount)=>void
    dominioSFE: string
}

function removeMaskTelefone(telefone: string){
    return telefone.replace(/[^0-9]/g, '');
}

export const FormDadosAdicionais = ({state, nextSetp, setState, prevSetp, dominioSFE}:FormDadosAdicionaisProps) => {
	const {
		register, handleSubmit, formState: { errors }, control, setError, clearErrors, getValues } = useForm<FormDadosAdicionaisSchema>({
		resolver: zodResolver(formDadosAdicionaisSchema),
		mode: "onBlur",
        defaultValues: {
            telefone: state.telefone,
            nascimento: state.nascimento,
            sexo: state.sexo
        }
	});
    const [cidades, setCidades] = useState<[] | Cidade[]>([]);
    const [searchText, setSearchText] = useState('')
	const [debouncedSearchText] = useDebounce(searchText, 500)


    const submit = (data:FormDadosAdicionaisSchema) => {
        const newState = {...state, ...data}
        newState.telefone = removeMaskTelefone(newState.telefone)
        setState(newState)
        nextSetp()
    }
    const validatorDadosUsuarioMutation = useMutation(
		({ telefone	}: { telefone: string }) => validarDadosUsuario({ apiUrl: dominioSFE, telefone }),
		{
			onError: ({ response }) => response,
		}
	);

    const isPhoneValid = (phone:string, country: string) => {
        try {
            const telefone = getValues('telefone')
            if(telefone){
                const isValid = phoneUtil.isValidNumberForRegion( phoneUtil.parseAndKeepRawInput(phone, country), country);
                if(isValid){
                    clearErrors('telefone')
                    validatorDadosUsuarioMutation.mutate({telefone:removeMaskTelefone(telefone)}, {
                        onError: ({response}) => {
                            if(response.status === 409){
                                setError('telefone', {message:'Esse telefone já está vinculado a uma conta'})
                            }
                            if(response.status === 404){
                                clearErrors('telefone')
                            }
                        }
                    })
                }else{
                    setError('telefone', {message: 'Telefone inválido'})
                }
            }
        } catch (error) {
            setError('telefone', {message: 'Telefone inválido'})
        }
    };

    const cidadeMutation = useMutation(
        (cidade:string)=>getCidades({apiUrl:dominioSFE, cidade}),
        {
            onSuccess:(response)=>{
                setCidades(response.cidades)
            }
        }
    )


    useEffect(()=>{
        if(debouncedSearchText.length >= 3){
            cidadeMutation.mutate(debouncedSearchText)
        }
    },[debouncedSearchText])

    return (
        <Form onSubmit={handleSubmit(submit)}>
            <Controller
                name="telefone"
                control={control}
                render={({ field: { onChange, value } }) => (
                    <PhoneInput
                        label="Telefone"
                        name="telefone"
                        value={value}
                        required
                        onChange={(telefone)=>{
                            onChange(telefone.phone)
                        }}
                        onBlur={(telefone)=>{
                            isPhoneValid(telefone.phone, telefone.country)
                        }}
                        variant={errors.telefone ? "error" : "standard"}
                        helperText={errors.telefone?.message}
                    />
                )}
            />

            <Input
                label="Nascimento"
                variant={errors.nascimento ? "error" : "standard"}
                helperText={errors.nascimento?.message}
                required
                type='date'
                {...register("nascimento")}
            />
            <Controller
                name="sexo"
                control={control}
                render={({ field: { onChange, value } }) => (
                    <FormControl fullWidth>
                        <InputLabel id="label-sexo" required shrink sx={{backgroundColor:"#FFF"}}>Sexo</InputLabel>
                        <Select
                            name="sexo"
                            labelId="label-sexo"
                            id="select-sexo"
                            label="Sexo"
                            value={value}
                            onChange={onChange}
                            required
                        >
                            <MenuItem value="masculino">Masculino</MenuItem>
                            <MenuItem value="feminino">Feminino</MenuItem>
                            <MenuItem value="outro">Outro</MenuItem>
                            <MenuItem value="uninf">Não informar</MenuItem>
                        </Select>
                    </FormControl>
                )}
            />
            <Controller
                name='cidades_idcidades'
                control={control}
                render={({ field: { onChange } }) => (
                    <Autocomplete
                        freeSolo
                        options={cidades}
                        getOptionLabel={(option) => option && typeof option === 'object'  ? option.nome : ''}
                        loading={true}
                        loadingText="Digite para pesquisar"
                        onChange={(_, value)=>{
                            if(value && typeof value === 'object' ){
                                onChange({target:{ value: value.idcidades}})
                            }
                        }}
                        renderOption={(props, option) => <MenuItem {...props} key={option.idcidades}>
                                <img
                                    loading="lazy"
                                    width="20"
                                    srcSet={`${option.bandeira} 2x`}
                                    src={option.bandeira}
                                    alt=""
                                />
                                <Typography>{option.nome} - {option.estado.uf}</Typography>
                            </MenuItem>
                        }
                        renderInput={(params) => (
                            <Input
                                {...params}
                                label="Cidade"
                                variant={errors.cidades_idcidades ? "error" : "standard"}
                                helperText={errors.cidades_idcidades?.message}
                                required
                                onChange={(event)=>setSearchText(event.target.value)}
                            />
                        )}
                    />
                )}
            />

            <ContainerButton>
                <Button onClick={()=>prevSetp()} fullWidth variant='outlined'>Voltar</Button>
                <Button type='submit' fullWidth>Proximo</Button>
            </ContainerButton>
        </Form >

    )
}