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: "",
};

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("نقش خود را وارد کنید"),
});

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-phone-number`} shrink>
                          جنسیت
                        </InputLabel>
                        <Select
                          labelId={`label-phone-number`}
                          id={"phone-number"}
                          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>
          </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;
