import { FC, useEffect, useState } from 'react';
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
import { LoadingState } from '../../types/general';
import { WASMDataF } from '../../types/WASMData';
import { CoherentCallStationEntryF, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import ActionBar from '../actionbar/ActionBar';

interface StationEntryProps {
  WASMData: WASMDataF;
  loadingState: LoadingState;
  setLoadingState: (newState: LoadingState) => void;
}

const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, setLoadingState }) => {
  const [upper1, setUpper1] = useState(WASMData.targetPayload.upper1);
  const [upper2, setUpper2] = useState(WASMData.targetPayload.upper2);
  const [upper3, setUpper3] = useState(WASMData.targetPayload.upper3);
  const [upper4, setUpper4] = useState(WASMData.targetPayload.upper4);
  const [lowerForward, setLowerForward] = useState(WASMData.targetPayload.lowerForward);
  const [lowerRear, setLowerRear] = useState(WASMData.targetPayload.lowerRear);
  const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
  const [fuelEnabled, setFuelEnabled] = useState(true);

  const ZFW = () => {
    if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.total);

    return Math.round(WASMData.livePayload.total);
  };
  const ZFWValid = () => {
    return ZFW() <= WASMData.limits.maxZFW;
  };
  const GW = () => {
    return fuel + ZFW();
  };
  const GWValid = () => {
    return GW() <= WASMData.limits.maxTOW;
  };

  const GSXActive = () => {
    return (
      (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) &&
      WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED
    );
  };

  const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => {
    if (!input) {
      setter(0);
      return;
    }

    const converted = parseInt(input);
    if (converted) {
      if (converted < 0) setter(0);
      else if (converted > maxValue) setter(maxValue);
      else setter(converted);
    }
  };

  const updateData = () => {
    CoherentCallStationEntryF(upper1, upper2, upper3, upper4, lowerForward, lowerRear);
  };

  useEffect(() => updateData(), [upper1, upper2, upper3, upper4, lowerForward, lowerRear]);
  useEffect(
    () =>
      setFuel((prev) => {
        if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel;
        return prev;
      }),
    [WASMData.userData.isER]
  );
  useEffect(() => {
    setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
  }, [WASMData.livePayload.fuel]);

  return (
    <>
      <div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
        <div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Fuel ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
            <input
              type="text"
              placeholder=""
              className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
              value={fuel}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
            <button
              className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
              data-ripple-light="true"
              onClick={() => {
                SimVar.SetSimVarValue(
                  'L:MD11_EFB_PAYLOAD_FUEL',
                  'lbs',
                  WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
                );
                SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
                setFuelEnabled(WASMData.livePayload.fuel === fuel);
              }}
              disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
            >
              Load Fuel
            </button>
          </div>
        </div>
      </div>

      <div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
        <div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Upper 1</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={upper1}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.upper1, setUpper1)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Upper 2</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={upper2}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.upper2, setUpper2)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Upper 3</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={upper3}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.upper3, setUpper3)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Upper 4</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={upper4}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.upper4, setUpper4)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Forward Cargo ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={lowerForward}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.lowerForward, setLowerForward)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>Aft Cargo ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
            <input
              type="text"
              placeholder=""
              className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
              value={lowerRear}
              onChange={(e) => handleInput(e.target.value, WASMData.limits.lowerRear, setLowerRear)}
              disabled={loadingState !== 'preview' || GSXActive()}
            />
          </div>
        </div>
      </div>

      <div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
        <div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>
              {loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} ZFW (
              {WASMData.userData.isImperial ? 'lbs' : 'kg'})
            </label>
            <input
              type="text"
              placeholder=""
              className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
              disabled
              value={ZFW()}
            />
          </div>
        </div>
        <div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
          <div className="flex w-full items-center justify-between text-xs">
            <label>
              {loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} GW (
              {WASMData.userData.isImperial ? 'lbs' : 'kg'})
            </label>
            <input
              type="text"
              placeholder=""
              className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
              disabled
              value={GW()}
            />
          </div>
        </div>
      </div>

      <ActionBar
        loadingState={loadingState}
        loadDisabled={!ZFWValid() || !GWValid()}
        GSXSync={WASMData.options.GSXSync}
        load={() => {
          setLoadingState('loaded');

          loadAircraft();
        }}
        unload={() => {
          setLoadingState('preview');

          unloadAircraft();
        }}
      />
    </>
  );
};

export default StationEntryF;
