import { FC, useEffect, useState } from 'react';
import { emptyAircraft } from '../../configs/shared';
import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_UPDATE_TARGET_EVENT } from '../../constants';
import { WASMDataPax } from '../../types/WASMData';
import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar';

interface StationEntryProps {
  WASMData: WASMDataPax;
  loadingState: 'preview' | 'accepted' | 'loaded';
  setLoadingState: (newState: StationEntryProps['loadingState']) => void;
  loadAircraft: () => void;
}

const ZFWEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, setLoadingState, loadAircraft }) => {
  const [targetZFWCG, setTargetZFWCG] = useState(WASMData.targetPayload.ZFWCG);
  const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
  const [ZFW, setZFW] = useState(Math.round(Math.max(WASMData.limits.minZFW, WASMData.targetPayload.total)));

  const _ZFW = () => {
    if (loadingState !== 'loaded') return ZFW;

    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 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 handleInputZFW = (input: string) => {
    if (!input) return;

    const converted = parseInt(input);
    if (converted) {
      if (converted < 0) setZFW(Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew));
      else if (converted > WASMData.limits.maxZFW) setZFW(WASMData.limits.maxZFW);
      else setZFW(converted);
    }
  };
  const handleBlur = (input: string) => {
    const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew);

    if (!input) {
      setZFW(minZFW);
      return;
    }

    const converted = parseInt(input);
    if (converted) {
      if (converted < minZFW) setZFW(minZFW);
      else if (converted > WASMData.limits.maxZFW) setZFW(WASMData.limits.maxZFW);
      else setZFW(converted);
    }

    updateData(converted);
  };

  useEffect(
    () =>
      setFuel((prev) => {
        if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel;
        return prev;
      }),
    [WASMData.userData.isER]
  );

  const updateData = (ZFWTarget?: number, CGTarget?: number) => {
    Coherent.call(
      COHERENT_COMBUS_WASM_CALL,
      COMM_BUS_UPDATE_TARGET_EVENT,
      JSON.stringify({
        mode: 1,
        ZFWTarget: ZFWTarget ?? ZFW,
        CGTarget: CGTarget ?? targetZFWCG,
      })
    );
  };

  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-t-md bg-zinc-600 p-2 px-4">
          <label>Target ZFW ({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={ZFW}
            onChange={(e) => handleInputZFW(e.target.value)}
            onBlur={(e) => handleBlur(e.target.value)}
            disabled={loadingState !== 'preview'}
          />
        </div>
        <div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
          <label>
            Target ZFWCG ({WASMData.limits.minCG} - {WASMData.limits.maxCG})
          </label>
          <CGSelect
            minCG={WASMData.limits.minCG}
            maxCG={WASMData.limits.maxCG}
            value={targetZFWCG}
            disabled={loadingState !== 'preview'}
            increase={() =>
              setTargetZFWCG((prev) => {
                const _new = prev + 0.1;
                updateData(undefined, _new);
                return _new;
              })
            }
            decrease={() =>
              setTargetZFWCG((prev) => {
                const _new = prev - 0.1;
                updateData(undefined, _new);
                return _new;
              })
            }
          />
        </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-md bg-zinc-600 p-2 px-4">
          <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'}
          />
          <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);
            }}
            disabled={loadingState !== 'preview' || fuel === Math.round(WASMData.livePayload.fuel)}
          >
            Load Fuel
          </button>
        </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">
          <label>
            {loadingState !== 'loaded' ? '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 className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
          <label>
            {loadingState !== 'loaded' ? '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>

      <ActionBar
        loadingState={loadingState}
        acceptDisabled={!GWValid()}
        accept={() => setLoadingState('accepted')}
        reject={() => setLoadingState('preview')}
        load={() => {
          setLoadingState('loaded');

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

          emptyAircraft();
        }}
      />
    </>
  );
};

export default ZFWEntryPax;
