import { Form, Formik } from "formik";
import FormGroup from "../components/FormGroup";
import type { SoundUploadValue } from "../../../types/types";
import { useSoundContext } from "../../../context/SoundContext";
import { toast } from "sonner";
import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard";
import { useFileUpload } from "../../../hooks/useFileUpload";

const SoundUpload = () => {
  const { state, dispatch } = useSoundContext();
  const { mutation } = useCameraBlackboard();
  const { mutation: fileMutation } = useFileUpload({
    queryKey: state.sightingSound ? [state.sightingSound] : undefined,
  });

  const initialValues: SoundUploadValue = {
    name: "",
    soundFile: null,
    soundFileName: "",
    soundUrl: "",
    uploadedAt: Date.now(),
  };

  const handleSubmit = async (values: SoundUploadValue) => {
    if (!values.soundFile) {
      toast.warning("Please select an audio file");
      return;
    }
    const alreadyExists = state?.soundOptions?.some((soundOption) => soundOption.name === values.name);
    if (state.soundOptions?.includes(values) || alreadyExists) {
      toast.warning("Sound already in list");
      return;
    }

    const updatedValues = {
      ...state,
      soundOptions: [...(state.soundOptions ?? []), values],
    };

    const result = await mutation.mutateAsync({
      operation: "INSERT",
      path: "soundSettings",
      value: updatedValues,
    });
    await fileMutation.mutateAsync(values.soundFile);
    if (result.reason !== "OK") {
      toast.error("Cannot update sound settings");
    }

    dispatch({ type: "ADD", payload: values });
  };

  return (
    <Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize>
      {({ setFieldValue, errors, setFieldError }) => (
        <Form>
          <label htmlFor="soundFile" className="">
            Sound File
          </label>
          <FormGroup>
            <input
              type="file"
              name="soundFile"
              id="sightingSoundinput"
              accept="audio/mpeg"
              className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5"
              onChange={(e) => {
                if (e.target?.files && e.target?.files[0]?.type === "audio/mpeg") {
                  const url = URL.createObjectURL(e.target.files[0]);
                  setFieldValue("soundUrl", url);
                  setFieldValue("name", e.target.files[0].name);
                  setFieldValue("soundFileName", e.target.files[0].name);
                  setFieldValue("soundFile", e.target.files[0]);
                  setFieldValue("uploadedAt", Date.now());
                  if (e?.target?.files[0]?.size >= 1 * 1024 * 1024) {
                    setFieldError("soundFile", "larger than 1mb");
                    toast.error("File larger than 1MB");
                    return;
                  }
                } else {
                  setFieldError("soundFile", "Not an mp3 file");
                  toast.error("Not an mp3 file");
                }
              }}
            />
          </FormGroup>

          <div className="mt-4 flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center">
            <p className="max-w-md text-slate-300">
              Uploaded Sound files will appear in the <span className="font-bold">drop downs</span> once they are
              uploaded. They can be used for any <span className="text-blue-400">Sighting,</span>{" "}
              <span className="text-emerald-400">Hotlist</span> or <span className="text-amber-600">NPED</span> hits.
            </p>
          </div>

          {errors.soundFile && <p className="text-red-500 text-sm mt-1">Not an mp3 file</p>}
          <button
            type="submit"
            className="w-1/4 text-white bg-green-700 hover:bg-green-800 font-small rounded-lg text-sm px-2 py-2.5 mt-[5%]"
            disabled={errors.soundFile ? true : false}
          >
            Upload
          </button>
        </Form>
      )}
    </Formik>
  );
};

export default SoundUpload;
