import LtrTextField from "@/core/components/LtrTextField";
import StyledForm from "@/core/components/StyledForm";
import validateNationalCode from "@/core/utils/nationalCodeValidation";
import useProvinces from "@/lib/hooks/useProvince";
import { yupResolver } from "@hookform/resolvers/yup";
import {
    Button,
    Chip,
    DialogActions,
    DialogContent,
    Divider,
    FormControl,
    FormHelperText,
    Grid,
    IconButton,
    InputAdornment,
    InputLabel,
    MenuItem,
    OutlinedInput,
    Select,
    Stack,
    TextField,
} from "@mui/material";
import { Controller, useForm } from "react-hook-form";
import { object, string } from "yup";
import { useMemo, useState } from "react";
import useRoles from "@/lib/hooks/useRoles";
import useRequest from "@/lib/hooks/useRequest";
import { CREATE_USER } from "@/core/utils/routes";
import { Visibility, VisibilityOff } from "@mui/icons-material";

const defaultValues = {
    full_name: "",
    username: "",
    position: "",
    gender: "male",
    national_id: "",
    phone_number: "",
    province_id: "",
    password: "",
    role_id: "",
    telephone_id: "",
};

const validationSchema = object().shape({
    full_name: string().required("نام و نام خانوادگی را وارد کنید"),
    username: string().required("نام کاربری را وارد کنید"),
    phone_number: string()
        .matches(/^09\d{9}$/, "شماره همراه باید با 09 شروع شود و 11 رقم باشد.")
        .required("شماره همراه را وارد کنید"),
    gender: string().required("جنسیت را وارد کنید"),
    national_id: string()
        .test("max", "کد ملی باید شامل 10 رقم باشد", (value) => value.toString().length === 10)
        .test("validation", "کد ملی صحیح نمی باشد", (value) => validateNationalCode(value))
        .required("کد ملی را وارد کنید"),
    password: string()
        .required("رمز عبور را وارد کنید")
        .matches(/^(?=.*[a-zA-Z])(?=.*\d).{8,}$/, "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد"),
    position: string().required("سمت را وارد کنید"),
    province_id: string().required("استان را وارد کنید"),
    role_id: string().required("نقش را وارد کنید"),
    telephone_id: string().required("شماره تماس داخلی را وارد کنید"),
});

const CreateUserForm = ({ setOpen, mutate }) => {
    const requestServer = useRequest({ notificationSuccess: true });
    const [showPassword, setShowPassword] = useState(false);
    const { provinces, errorProvinces, loadingProvinces } = useProvinces();
    const { roles, errorRoles, loadingRoles } = useRoles();

    const handleClickShowPassword = () => setShowPassword((show) => !show);

    const provinceSelectOptions = useMemo(() => {
        if (loadingProvinces) {
            return [{ value: "loading", label: "در حال بارگذاری..." }];
        }
        if (errorProvinces) {
            return [{ value: "error", label: "خطا در بارگذاری" }];
        }
        return [
            { value: "", label: "انتخاب استان" },
            ...provinces.map((province) => ({
                value: province.id,
                label: province.name,
            })),
        ];
    }, [provinces, errorProvinces, loadingProvinces]);

    const roleSelectOptions = useMemo(() => {
        if (loadingRoles) {
            return [{ value: "loading", label: "در حال بارگذاری..." }];
        }
        if (errorRoles) {
            return [{ value: "error", label: "خطا در بارگذاری" }];
        }
        return [
            { value: "", label: "انتخاب نقش" },
            ...roles.map((role) => ({
                value: role.id,
                label: role.name_fa,
            })),
        ];
    }, [roles, errorRoles, loadingRoles]);

    const {
        control,
        handleSubmit,
        formState: { isSubmitting, errors },
    } = useForm({ defaultValues, resolver: yupResolver(validationSchema) });

    const onSubmit = async (data) => {
        const formData = new FormData();
        Object.keys(data).forEach((key) => {
            formData.append(key, data[key]);
        });
        try {
            await requestServer(CREATE_USER, "post", {
                data: formData,
            });
            setOpen(false);
            mutate();
        } catch (error) {}
    };

    return (
        <>
            <DialogContent dividers>
                <Divider sx={{ mb: 3 }}>
                    <Chip color="primary" variant="outlined" label="کاربر جدید" />
                </Divider>
                <StyledForm
                    id="createUserForm"
                    onSubmit={handleSubmit(onSubmit)}
                    style={{ width: "100%", height: "100%" }}
                >
                    <Stack spacing={2}>
                        <Grid container spacing={2}>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <LtrTextField
                                                {...field}
                                                label="نام کاربری"
                                                variant="outlined"
                                                fullWidth
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"username"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <LtrTextField
                                                {...field}
                                                label="رمز عبور"
                                                variant="outlined"
                                                type={showPassword ? "text" : "password"}
                                                slotProps={{
                                                    input: {
                                                        startAdornment: (
                                                            <InputAdornment position="start">
                                                                <IconButton onClick={handleClickShowPassword}>
                                                                    {showPassword ? <VisibilityOff /> : <Visibility />}
                                                                </IconButton>
                                                            </InputAdornment>
                                                        ),
                                                    },
                                                }}
                                                fullWidth
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"password"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <TextField
                                                {...field}
                                                label="نام و نام خانوادگی"
                                                variant="outlined"
                                                fullWidth
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"full_name"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <TextField
                                                {...field}
                                                label="سمت"
                                                variant="outlined"
                                                fullWidth
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"position"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <LtrTextField
                                                {...field}
                                                label="شماره همراه"
                                                variant="outlined"
                                                fullWidth
                                                type="tel"
                                                onChange={(e) => {
                                                    const inputValue = event.target.value;
                                                    if (isNaN(Number(inputValue))) {
                                                        return;
                                                    }
                                                    if (inputValue.length > 11) {
                                                        return;
                                                    }
                                                    field.onChange(inputValue);
                                                }}
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"phone_number"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <FormControl fullWidth error={!!error}>
                                                <InputLabel id={`label-gender`} shrink>
                                                    جنسیت
                                                </InputLabel>
                                                <Select
                                                    labelId={`label-gender`}
                                                    id={"gender"}
                                                    name={`gender`}
                                                    value={field.value}
                                                    input={<OutlinedInput label={"جنسیت"} />}
                                                    onChange={(e) => field.onChange(e.target.value)}
                                                    displayEmpty
                                                >
                                                    <MenuItem value={"male"}>مرد</MenuItem>
                                                    <MenuItem value={"female"}>زن</MenuItem>
                                                </Select>
                                                <FormHelperText error={!!error} sx={{ mt: 1 }}>
                                                    {!!error && error.message}
                                                </FormHelperText>
                                            </FormControl>
                                        );
                                    }}
                                    name={"gender"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <LtrTextField
                                                {...field}
                                                label="شماره ملی"
                                                variant="outlined"
                                                fullWidth
                                                type="tel"
                                                onChange={(e) => {
                                                    const inputValue = event.target.value;
                                                    if (isNaN(Number(inputValue))) {
                                                        return;
                                                    }
                                                    if (inputValue.length > 10) {
                                                        return;
                                                    }
                                                    field.onChange(inputValue);
                                                }}
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"national_id"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <FormControl fullWidth error={!!error}>
                                                <InputLabel id={`label-province`} shrink>
                                                    استان
                                                </InputLabel>
                                                <Select
                                                    labelId={`label-province`}
                                                    id={"province"}
                                                    name={`province_id`}
                                                    value={field.value}
                                                    input={<OutlinedInput label={"استان"} />}
                                                    onChange={(e) => field.onChange(e.target.value)}
                                                    displayEmpty
                                                >
                                                    {provinceSelectOptions.map((option) => (
                                                        <MenuItem key={option.value} value={option.value}>
                                                            {option.label}
                                                        </MenuItem>
                                                    ))}
                                                </Select>
                                                <FormHelperText error={!!error} sx={{ mt: 1 }}>
                                                    {!!error && error.message}
                                                </FormHelperText>
                                            </FormControl>
                                        );
                                    }}
                                    name={"province_id"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <FormControl fullWidth error={!!error}>
                                                <InputLabel id={`label-role`} shrink>
                                                    نقش
                                                </InputLabel>
                                                <Select
                                                    labelId={`label-role`}
                                                    id={"role"}
                                                    name={`role_id`}
                                                    value={field.value}
                                                    input={<OutlinedInput label={"نقش"} />}
                                                    onChange={(e) => field.onChange(e.target.value)}
                                                    displayEmpty
                                                >
                                                    {roleSelectOptions.map((option) => (
                                                        <MenuItem key={option.value} value={option.value}>
                                                            {option.label}
                                                        </MenuItem>
                                                    ))}
                                                </Select>
                                                <FormHelperText error={!!error} sx={{ mt: 1 }}>
                                                    {!!error && error.message}
                                                </FormHelperText>
                                            </FormControl>
                                        );
                                    }}
                                    name={"role_id"}
                                />
                            </Grid>
                            <Grid size={{ xs: 12, md: 6 }}>
                                <Controller
                                    control={control}
                                    render={({ field, fieldState: { error } }) => {
                                        return (
                                            <LtrTextField
                                                {...field}
                                                label="شماره تماس داخلی"
                                                variant="outlined"
                                                fullWidth
                                                type="tel"
                                                error={!!error}
                                                helperText={!!error && error.message}
                                            />
                                        );
                                    }}
                                    name={"telephone_id"}
                                />
                            </Grid>
                        </Grid>
                    </Stack>
                </StyledForm>
            </DialogContent>
            <DialogActions>
                <Button
                    disabled={isSubmitting}
                    variant="outlined"
                    color="secondary"
                    size="large"
                    onClick={() => setOpen(false)}
                >
                    بستن
                </Button>
                <Button
                    type="submit"
                    disabled={isSubmitting}
                    form="createUserForm"
                    size="large"
                    autoFocus
                    variant="contained"
                >
                    {isSubmitting ? "در حال ثبت کاربر جدید..." : "ثبت کاربر جدید"}
                </Button>
            </DialogActions>
        </>
    );
};

export default CreateUserForm;
