import { FC, useEffect, useState } from 'react';
import { FormFieldProps } from 'mystique/registry/FieldRegistry';
import {
  FormControl,
  FormHelperText,
  makeStyles,
  Paper,
  TextField,
} from '@material-ui/core';
import { getQuery, OperationResult } from 'mystique/hooks/getQuery';
import { Autocomplete } from '@material-ui/lab';
import { getSettings } from 'mystique/hooks/getSettings';
import { useAuth } from 'mystique/hooks/useAuth';
import { useI18n } from 'mystique/hooks/useI18n';
import { defaultReturnDestinationLocationSettingName } from '../../../constants/SettingNames';

interface Location {
  tag: string;
  id: string;
  ref: string;
  name: string;
}

const query = `
  {
    locations(first: 5000) {
      edges {
        node {
          id
          ref
          name
          attributes {
            name
            value
          }
        }
      }
    }
  }
`;

const locationQuery = `
  query getLocationByRef($ref: String!) {
    locations(ref: [$ref]) {
      edges {
        node {
          id
          ref
          name
        }
      }
    }
  }
`;

export const DestinationLocationSelector: FC<FormFieldProps<any>> = (props) => {
  const [locations, setLocations] = useState<Location[]>([]);
  const [location, setLocation] = useState<Location>();
  const [defaultLocations, setDefaultLocations] = useState<Location[]>([]);
  const [hide, setHide] = useState<boolean>(false);
  const { translateOr } = useI18n();
  const auth = useAuth();
  const classes = useStyles();

  useEffect(() => {
    const value =
      window.sessionStorage.getItem('HIDE_DESTINATION_LOCATION') ?? 'true';
    setHide(value === 'true');
  }, [window.sessionStorage.getItem('HIDE_DESTINATION_LOCATION')]);

  useEffect(() => {
    setLocation(
      auth?.context.current.contextType === 'location'
        ? locations.find((value) => value.id === auth.context.current.contextId)
        : locations[0],
    );
  }, [locations]);

  useEffect(() => {
    getSettings(
      { setting: defaultReturnDestinationLocationSettingName },
      parseInt(auth.context.current.contextId),
    ).then((value) => {
      if (value.setting.status == 'ok') {
        getQuery(locationQuery, { ref: value.setting.result.value }).then(
          (value: any) => {
            const defLocations: Location[] = [];
            value.data.locations.edges.forEach((edge: any) =>
              defLocations.push({
                tag: translateOr([
                  'fc.sf.ui.returns.orders.createReturnOrder.destinationLocation.default.label',
                  'Default',
                ]),
                id: edge.node.id,
                name: edge.node.name,
                ref: edge.node.ref,
              } as Location),
            );
            setDefaultLocations(defLocations);
          },
        );
      }
    });
  }, []);

  useEffect(() => {
    getQuery(query).then((value: OperationResult) => {
      if (!value.error) {
        const result: any[] = [];
        value.data.locations.edges.forEach((edge: any) => {
          const acceptsReturns = edge.node.attributes?.find(
            (a: any) => a.name === 'ACCEPTS_RETURNS',
          );
          if (
            !acceptsReturns ||
            (typeof acceptsReturns.value === 'string'
              ? acceptsReturns.value.toLowerCase() === 'true'
              : acceptsReturns.value)
          ) {
            result.push({
              tag: translateOr([
                'fc.sf.ui.returns.orders.createReturnOrder.destinationLocation.other.label',
                'Other Locations',
              ]),
              id: edge.node.id,
              ref: edge.node.ref,
              name: edge.node.name,
            } as Location);
          }
        });
        setLocations([
          ...defaultLocations,
          ...result.sort((a: Location, b: Location) =>
            a.name.localeCompare(b.name),
          ),
        ]);
      }
    });
  }, [defaultLocations]);

  useEffect(() => {
    if (location) {
      props.onChange(location?.ref);
    } else {
      props.onChange(null);
    }
  }, [location]);

  const handleChange = (newLocation: Location) => {
    setLocation(newLocation);
  };

  const handleOnBlur = () => {
    props && props.onBlur && props.onBlur();
  };

  return (
    <>
      {!hide && (
        <Paper variant="elevation" className={classes.paper}>
          <FormControl fullWidth error={!!props.error}>
            <Autocomplete
              options={locations}
              getOptionLabel={(location) =>
                `${location.name} (${location.ref})`
              }
              onChange={(_, newLocation) =>
                handleChange(newLocation as Location)
              }
              onBlur={handleOnBlur}
              value={location || null}
              getOptionSelected={(option, value) => option.id === value.id}
              groupBy={(option) => option.tag}
              renderInput={(params) => (
                <TextField
                  error={!!props.error}
                  {...params}
                  label={props.label}
                />
              )}
            />
            {props.error && <FormHelperText>{props.error}</FormHelperText>}
          </FormControl>
        </Paper>
      )}
    </>
  );
};

const useStyles = makeStyles(() => ({
  paper: {
    padding: '5px',
  },
}));

export default DestinationLocationSelector;
