import { Field, Form, Formik, useFormikContext } from "formik";
import FormGroup from "../components/FormGroup";
import { useEffect, useState } from "react";
import { faEyeSlash, faEye } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useCameraOutput } from "../../../hooks/useCameraOutput";
import type {
  InitialValuesForm,
  InitialValuesFormErrors,
} from "../../../types/types";
import { toast } from "sonner";

const ChannelFields = () => {
  const [showPwd, setShowPwd] = useState(false);
  const { backOfficeQuery, backOfficeMutation } = useCameraOutput();

  const backOfficeURL = backOfficeQuery?.data?.propBackofficeURL?.value;
  const username = backOfficeQuery?.data?.propUsername?.value;
  const password = backOfficeQuery?.data?.propPassword?.value;
  const connectTimeoutSeconds =
    backOfficeQuery?.data?.propConnectTimeoutSeconds?.value;
  const readTimeoutSeconds =
    backOfficeQuery?.data?.propReadTimeoutSeconds?.value;

  const initialValues: InitialValuesForm = {
    backOfficeURL: backOfficeURL ?? "",
    username: username ?? "",
    password: password ?? "",
    connectTimeoutSeconds: Number(connectTimeoutSeconds),
    readTimeoutSeconds: Number(readTimeoutSeconds),
  };

  const handleSubmit = async (values: InitialValuesForm) => {
    await backOfficeMutation.mutateAsync(values);
  };

  const ValidationToastOnce = () => {
    const { submitCount, isValid } = useFormikContext();
    useEffect(() => {
      if (submitCount > 0 && !isValid) {
        toast.error("Check fields are filled in");
      }
    }, [submitCount, isValid]);
    return null;
  };

  const validateValues = (
    values: InitialValuesForm
  ): InitialValuesFormErrors => {
    const errors: InitialValuesFormErrors = {};

    const url = values.backOfficeURL?.trim();
    const username = values.username?.trim();
    const password = values.password?.trim();

    if (!url) {
      errors.backOfficeURL = "Required";
    }

    if (!username) errors.username = "Required";
    if (!password) errors.password = "Required";

    const read = Number(values.readTimeoutSeconds);
    if (!Number.isFinite(read)) {
      errors.readTimeoutSeconds = "Must be a number";
    } else if (read < 0) {
      errors.readTimeoutSeconds = "Must be ≥ 0";
    }

    const connect = Number(values.connectTimeoutSeconds);
    if (!Number.isFinite(connect)) {
      errors.connectTimeoutSeconds = "Must be a number";
    } else if (connect < 0) {
      errors.connectTimeoutSeconds = "Must be ≥ 0";
    }

    return errors;
  };

  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      enableReinitialize
      validate={validateValues}
    >
      {({ errors, touched, isSubmitting }) => (
        <Form>
          <div className="flex flex-col space-y-2 px-2">
            <FormGroup>
              <label htmlFor="backoffice" className="m-0">
                Back Office URL
              </label>

              <Field
                name={"backOfficeURL"}
                type="text"
                id="backoffice"
                placeholder="https://www.backoffice.com"
                className={`p-1.5 border ${
                  errors.backOfficeURL && touched.backOfficeURL
                    ? "border-red-500"
                    : "border-gray-400 "
                } rounded-lg w-full md:w-60`}
              />
            </FormGroup>
            <FormGroup>
              <label htmlFor="username">Username</label>
              <Field
                name={"username"}
                type="text"
                id="username"
                placeholder="Back office username"
                className={`p-1.5 border ${
                  errors.username && touched.username
                    ? "border-red-500"
                    : "border-gray-400 "
                } rounded-lg w-full md:w-60`}
              />
            </FormGroup>
            <FormGroup>
              <label htmlFor="password">Password</label>
              <Field
                name={"password"}
                type={showPwd ? "text" : "password"}
                id="password"
                placeholder="Back office password"
                className={`p-1.5 border ${
                  errors.password && touched.password
                    ? "border-red-500"
                    : "border-gray-400 "
                } rounded-lg w-full md:w-60`}
              />
              <FontAwesomeIcon
                type="button"
                className="absolute right-5 end-0"
                onClick={() => setShowPwd((s) => !s)}
                icon={showPwd ? faEyeSlash : faEye}
              />
            </FormGroup>
            <FormGroup>
              <label htmlFor="connectTimeoutSeconds">
                Connect Timeout Seconds
              </label>
              <Field
                name={"connectTimeoutSeconds"}
                type="number"
                id="connectTimeoutSeconds"
                className={`p-1.5 border ${
                  errors.connectTimeoutSeconds && touched.connectTimeoutSeconds
                    ? "border-red-500"
                    : "border-gray-400 "
                } rounded-lg w-full md:w-60`}
              />
            </FormGroup>
            <FormGroup>
              <label htmlFor="readTimeoutSeconds">Read Timeout Seconds</label>
              <Field
                name={"readTimeoutSeconds"}
                type="number"
                id="readTimeoutSeconds"
                placeholder="https://example.com"
                className={`p-1.5 border ${
                  errors.readTimeoutSeconds && touched.readTimeoutSeconds
                    ? "border-red-500"
                    : "border-gray-400 "
                } rounded-lg w-full md:w-60`}
              />
            </FormGroup>
          </div>
          <button
            type="submit"
            className="bg-[#26B170] text-white px-4 py-2 rounded hover:bg-green-700 transition w-full md:w-[50%]"
          >
            {isSubmitting || backOfficeMutation.isPending
              ? "Saving..."
              : "Save Changes"}
          </button>
          <ValidationToastOnce />
        </Form>
      )}
    </Formik>
  );
};

export default ChannelFields;
