import { Field, FieldArray } from "formik";
import type { FormTypes, InitialValuesFormErrors, OutputDataResponse } from "../../../types/types";
import { useEffect, useMemo } from "react";
import { useOptionalConstants } from "../hooks/useOptionalConstants";

type ChannelFieldsProps = {
  values: FormTypes;
  errors: InitialValuesFormErrors;
  touched: {
    connectTimeoutSeconds?: boolean | undefined;
    readTimeoutSeconds?: boolean | undefined;
  };
  outputData?: OutputDataResponse;
  onSetFieldValue: (field: string, value: string, shouldValidate?: boolean | undefined) => void;
};

const ChannelFields = ({ errors, touched, values, outputData, onSetFieldValue }: ChannelFieldsProps) => {
  const { optionalConstantsQuery } = useOptionalConstants(outputData?.id?.split("-")[1] || "");
  const optionalConstants = optionalConstantsQuery?.data;

  const channelFieldsObject = useMemo(() => {
    return {
      connectTimeoutSeconds: outputData?.propConnectTimeoutSeconds?.value || "5",
      readTimeoutSeconds: outputData?.propReadTimeoutSeconds?.value || "15",
      backOfficeURL: outputData?.propBackofficeURL?.value || "",
      username: outputData?.propUsername?.value || "",
      password: outputData?.propPassword?.value || "",
      SCID: optionalConstants?.propSourceIdentifier?.value || "",
      timestampSource: optionalConstants?.propTimeZoneType?.value || "UTC",
      GPSFormat: optionalConstants?.propGpsFormat?.value || "Minutes",
      FFID: optionalConstants?.propFeedIdentifier?.value || "",
    };
  }, [
    optionalConstants?.propFeedIdentifier?.value,
    optionalConstants?.propGpsFormat?.value,
    optionalConstants?.propSourceIdentifier?.value,
    optionalConstants?.propTimeZoneType?.value,
    outputData?.propBackofficeURL?.value,
    outputData?.propConnectTimeoutSeconds?.value,
    outputData?.propPassword?.value,
    outputData?.propReadTimeoutSeconds?.value,
    outputData?.propUsername?.value,
  ]);

  useEffect(() => {
    for (const [key, value] of Object.entries(channelFieldsObject)) {
      onSetFieldValue(key, value);
    }
  }, [channelFieldsObject, onSetFieldValue, outputData]);

  return (
    <div className="flex flex-col gap-4 p-4">
      {values.format.toLowerCase() !== "ftp" ? (
        <>
          <div className="flex flex-row justify-between">
            <label htmlFor="backoffice" className="block mb-2 font-medium">
              Back Office URL
            </label>
            <Field
              name={"backOfficeURL"}
              type="text"
              id="backoffice"
              placeholder="https://www.backoffice.com"
              className={`p-1.5 border border-gray-400 rounded-lg w-full md:w-60`}
            />
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="username" className="block mb-2 font-medium">
              Username
            </label>
            <Field
              name={"username"}
              type="text"
              id="username"
              placeholder="Back office username"
              className={`p-1.5 border border-gray-400 rounded-lg w-full md:w-60`}
            />
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="password">Password</label>
            <Field
              name={"password"}
              type={"password"}
              id="password"
              placeholder="Back office password"
              className={`p-1.5 border border-gray-400 rounded-lg w-full md:w-60`}
            />
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="readTimeoutSeconds">Read Timeout Seconds</label>
            <Field
              name={"readTimeoutSeconds"}
              type="number"
              id="readTimeoutSeconds"
              placeholder="https://example.com"
              className={`p-1.5 border border-gray-400  rounded-lg w-full md:w-60`}
            />
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="connectTimeoutSeconds">Connect Timeout Seconds</label>
            <Field
              name={"connectTimeoutSeconds"}
              type="number"
              id="connectTimeoutSeconds"
              className={`p-1.5 border border-gray-400 rounded-lg w-full md:w-60`}
            />
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="overviewQuality">Overview quality and scale</label>
            <Field
              name={"overviewQuality"}
              as="select"
              id="overviewQuality"
              className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
            >
              <option value={"HIGH"}>High</option>
              <option value={"MEDIUM"}>Medium</option>
              <option value={"LOW"}>Low</option>
            </Field>
          </div>
          <div className="flex flex-row justify-between">
            <label htmlFor="cropSizeFactor">Crop Size Factor</label>
            <Field
              name={"cropSizeFactor"}
              as="select"
              id="cropSizeFactor"
              className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
            >
              <option value={"FULL"}>Full</option>
              <option value={"3/4"}>3/4</option>
              <option value={"1/2"}>1/2</option>
              <option value={"1/4"}>1/4</option>
            </Field>
          </div>
          {values.format.toLowerCase() === "utmc" && (
            <>
              <div className="border-b border-gray-500 my-3">
                <h2 className="font-bold">{values.format} Constants</h2>
              </div>

              <div className="flex flex-row justify-between">
                <label htmlFor="SCID">Source ID / Camera ID</label>
                <Field
                  name={"SCID"}
                  type="text"
                  id="SCID"
                  placeholder="DEF345"
                  className={`p-1.5 border ${
                    errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 "
                  } rounded-lg w-full md:w-60`}
                />
              </div>
              <div className="flex flex-row justify-between">
                <label htmlFor="timestampSource">Timestamp Source</label>
                <Field
                  name={"timestampSource"}
                  as="select"
                  id="timestampSource"
                  className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
                >
                  <option value={"UTC"}>UTC</option>
                  <option value={"local"}>Local</option>
                </Field>
              </div>
              <div className="flex flex-row justify-between">
                <label htmlFor="GPSFormat">GPS Format</label>
                <Field
                  name={"GPSFormat"}
                  as="select"
                  id="GPSFormat"
                  className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
                >
                  <option value={"Minutes"}>Minutes</option>
                  <option value={"Decimal Degrees"}>Decimal degrees</option>
                </Field>
              </div>
            </>
          )}
          {values.format?.toLowerCase() === "bof2" && (
            <>
              <div className="space-y-3">
                <div className="border-b border-gray-500 my-3">
                  <h2 className="font-bold">{values.format} Constants</h2>
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="FFID">Feed ID / Force ID</label>
                  <Field
                    name={"FFID"}
                    type="text"
                    id="FFID"
                    placeholder="ABC123"
                    className={`p-1.5 border ${
                      errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 "
                    } rounded-lg w-full md:w-60`}
                  />
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="SCID">Source ID / Camera ID</label>
                  <Field
                    name={"SCID"}
                    type="text"
                    id="SCID"
                    placeholder="DEF345"
                    className={`p-1.5 border ${
                      errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 "
                    } rounded-lg w-full md:w-60`}
                  />
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="timestampSource">Timestamp Source</label>
                  <Field
                    name={"timestampSource"}
                    as="select"
                    id="timestampSource"
                    className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
                  >
                    <option value={"UTC"}>UTC</option>
                    <option value={"LOCAL"}>Local</option>
                  </Field>
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="GPSFormat">GPS Format</label>
                  <Field
                    name={"GPSFormat"}
                    as="select"
                    id="GPSFormat"
                    className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
                  >
                    <option value={"Minutes"}>Minutes</option>
                    <option value={"Decimal Degrees"}>Decimal degrees</option>
                  </Field>
                </div>
              </div>
              <div className="space-y-3">
                <div className="border-b border-gray-500 my-3">
                  <h2 className="font-bold">{values.format} Lane ID Config</h2>
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="LID1">Lane ID 1 (Camera A)</label>
                  <Field
                    name={"LID1"}
                    type="text"
                    id="LID1"
                    placeholder="10"
                    className={`p-1.5 border ${
                      errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 "
                    } rounded-lg w-full md:w-60`}
                  />
                </div>
                <div className="flex flex-row justify-between">
                  <label htmlFor="LID2">Lane ID 2 (Camera B)</label>
                  <Field
                    name={"LID2"}
                    type="text"
                    id="LID2"
                    placeholder="20"
                    className={`p-1.5 border ${
                      errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 "
                    } rounded-lg w-full md:w-60`}
                  />
                </div>
              </div>
            </>
          )}
          <div className="border-b border-gray-500 my-3">
            <h2 className="font-bold">Custom Fields</h2>
          </div>
          <div className="items-center mb-4">
            <FieldArray name="customFields">
              {(arrayHelpers) => (
                <>
                  {values?.customFields?.map((_, index) => (
                    <div key={index} className="flex flex-row justify-between items-center mb-4">
                      <label htmlFor={`customFields.${index}`} className="mr-2">
                        Custom Field {index + 1}
                      </label>
                      <Field
                        name={`customFields.${index}`}
                        key={index}
                        className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
                        placeholder={`Enter Custom Field ${index + 1}`}
                        autoComplete="off"
                      />
                    </div>
                  ))}
                  <button
                    type="button"
                    onClick={() => arrayHelpers.push("")}
                    className="mr-2 border p-2 rounded-lg hover:bg-gray-700 hover:cursor-pointer"
                  >
                    Add Custom Field
                  </button>
                  {values?.customFields && values?.customFields?.length > 0 && (
                    <button
                      type="button"
                      onClick={() => arrayHelpers.pop()}
                      className="border p-2 rounded-lg hover:bg-gray-700 hover:cursor-pointer"
                    >
                      Remove Custom Field
                    </button>
                  )}
                </>
              )}
            </FieldArray>
          </div>
        </>
      ) : (
        <></>
      )}
    </div>
  );
};

export default ChannelFields;
