import ModalWrapper from '../wrappers/ModalWrapper'
import { ADDRESS_GROUPS, AU_STATES, NZ_STATES, TIMESLOT_REQUIRED, USER_ROLES } from '../lib/constants'
import MultiSelectDropDownComp from '../ui/MultiSelectDropDownComp';
import SelectorComp from '../ui/SelectorComp';
import { Box, Button, Divider, Grid } from '@material-ui/core';
import InputBox from '../ui/InputBox';
import { styled } from '@material-ui/core/styles';
import AddIcon from '@material-ui/icons/Add';
import { Formik, Form} from 'formik';
import { useCallback, useEffect, useState } from 'react';
import { AppState } from '../../Redux';
import { useSelector } from 'react-redux';
import { ICompanyInfo } from '../../../../Application/DTOs/CompanyDto/CompanyDto.type';
import { Address } from '../../Api/Address/Address';
import { toast } from 'react-toastify';
import { WebStorage } from '../../Utilities/WebStorage';
import { TOKEN_STORAGE_KEY } from '../../Types/Constants';
import { checkIsEmpty } from '../lib/helper';
import { validationAddAddressSchema } from '../lib/validationSchema';
import MapAutocomplete from '../../Components/Common/MapAutocomplete/MapAutocomplete';
import MapAddress from '../../BP/MapAddress';
import DynamicPalletAccounts from '../../Components/Common/PalletAccount/DynamicPallets';

const addressService = new Address();
const storage = new WebStorage();

interface CreateAddressModalProps {
  open: boolean;
  close: (isSaved?: boolean) => void;
  fetchAddresses: () => void;
  companyId?: number;
  customerId?: number;
}

const ButtonFlex = styled(Box)({
  gap: "20px",
  display: "flex",
  justifyContent: "flex-end",
  alignItems: "center",
  margin: "20px 0"
})

const MarginSpace = styled(Box)({
  padding: "10px 0"
});

const HrDivider = styled(Divider)({
  margin: "0 0 20px 0"
});

const CreateAddressModal = ({ open, close, fetchAddresses, companyId, customerId }: CreateAddressModalProps) => {
  const { ADMIN_USER, SUPER_ADMIN } = USER_ROLES;
  const user = useSelector((state: AppState) => state.user.response);
  const isUserAdmin = user?.type === ADMIN_USER;
  const isSuperAdmin = user?.type === SUPER_ADMIN;
  const companyDropdownData = useSelector((state: AppState) => state.company);
  const countryInitial = isSuperAdmin || isUserAdmin ? "australia" : user?.company?.country || "australia";
  const [address, setAddress] = useState('');
  const [customersData, setCustomersData] = useState<any[]>([]);
  const [palletAccounts, setPalletAccounts] = useState([]);

  useEffect(() => {
    if (companyId) fetchCustomerApi(companyId);
  }, [companyId]);

  const fetchCustomerApi = async (compId: string | number) => {
    try {
      const myHeaders = new Headers({
        Authorization: `Bearer ${storage.retrieve(TOKEN_STORAGE_KEY)}`,
      });

      const requestOptions: RequestInit = {
        method: 'GET',
        headers: myHeaders,
        redirect: 'follow',
      };

      const response = await fetch(process.env.REACT_APP_NEW_BASE_URL + `/v1/customer/list?offset=0&limit=10&company_id=${compId}&is_admin=false&active=false`,
        requestOptions
      );

      const result = await response.json();
      setCustomersData(result.rows)
    } catch (err) {
      console.error('Fetch error:', err);
    }
  };

  const initialValues = {
    country: countryInitial || 'australia',
    company: companyId,
    customer: customerId,
    groupType: "",
    address: "",
    receivingHours: "",
    instruction: "",
    stateRegionType: "",
    stateType: "",
    suburbCity: "",
    postcode: "",
    latitude: null,
    longitude: null,
    cperminus: "",
    truck_requirement: "",
    timeslot_required: "",
    timeslot_booking_info: "",
    ship_id: "",
    pallet_restrictions: "",
    pallet_restrictions_instructions: "",
  };

  const handleSubmit = async (values: any, { setSubmitting, resetForm }: any) => {
    try {
      const newAddressData = {
        registered_address: checkIsEmpty(values.address),
        company_id: checkIsEmpty(values.company),
        customer_id: checkIsEmpty(values.customer),
        country: checkIsEmpty(values.country),
        address_group: checkIsEmpty(values.groupType),
        instruction: checkIsEmpty(values.instruction),
        latitude: checkIsEmpty(values.latitude),
        longitude: checkIsEmpty(values.longitude),
        postcode: checkIsEmpty(values.postcode),
        receiving_hours: checkIsEmpty(values.receivingHours),
        state: checkIsEmpty(values.stateRegionType),
        city: checkIsEmpty(values.suburbCity),
        is_common: false,
        is_land_freight: true,
        is_sea_freight: false,
        street_number: checkIsEmpty(values.address),
        palletAccounts: palletAccounts,
        C: checkIsEmpty(values.cperminus),
        truck_requirements: checkIsEmpty(values.truck_requirement),
        timeslot_required: checkIsEmpty(values.timeslot_required),
        timeslot_booking_info: checkIsEmpty(values.timeslot_booking_info),
        ship_id: values.ship_id,
        pallet_restrictions: values.pallet_restrictions,
        pallet_restriction_instructions: values.pallet_restrictions_instructions
      }
      const response = await addressService.create(newAddressData)

      if (response?.status == 201) {
        toast.success(response?.data);
        resetForm();
        setPalletAccounts([])
        fetchAddresses();
        close(true);
      }
    } catch (err) {
      toast.error(err?.response?.data ?? "An error occurred");
    } finally {
      setSubmitting(false);
    }
  }

  const handleMapAddressSelect = useCallback(
    (mapAddress: MapAddress, setFieldValue: (field: string, value: any) => void) => {
      if (!mapAddress) return;
      setFieldValue('address', mapAddress.formattedAddress);
      setFieldValue('suburbCity', mapAddress.city);
      setFieldValue('postcode', mapAddress.postalCode);
      setFieldValue('stateRegionType', mapAddress.state);
      setFieldValue('latitude', mapAddress.lat);
      setFieldValue('longitude', mapAddress.long);
    },
    []
  );
  const handlePalletAccountsChange = (newPalletAccounts) => {
    setPalletAccounts(newPalletAccounts);
  };
  const handleClose = (resetForm: () => void) => {
    resetForm();
    setPalletAccounts([])
    close();
  };

  return (
    <>
      <Formik
        initialValues={initialValues}
        onSubmit={handleSubmit}
        enableReinitialize={true}
        validationSchema={validationAddAddressSchema}
      >
        {({ isSubmitting, handleChange, setFieldValue, values, errors, touched, resetForm }) => (
          <ModalWrapper
            open={open}
            onClose={() => handleClose(resetForm)}
            heading="Add New Address"
          >
            <HrDivider />
            <Form>
              <MarginSpace>
                <Grid container spacing={3} >
                  <Grid item xs={4} >
                    <SelectorComp
                      label="Group*"
                      onChange={handleChange}
                      options={ADDRESS_GROUPS}
                      value={values.groupType}
                      name="groupType"
                      error={errors.groupType && touched.groupType ? errors.groupType : null}
                    />
                  </Grid>
                  <Grid item xs={4} >
                    <MultiSelectDropDownComp<ICompanyInfo>
                      options={companyDropdownData.list}
                      label="Company/Customer Name*"
                      name="company"
                      value={values.company}
                      getOptionLabel={(option) => option.companyName}
                      getOptionId={(option) => option.id}
                      onChange={(event, selectedOption) => {
                        const id = selectedOption ? selectedOption.id : ""
                        setFieldValue("company", id);
                        if (id) {
                          fetchCustomerApi(id)
                        }
                      }}
                      error={errors.company && touched.company ? errors.company : null}
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <MultiSelectDropDownComp<any>
                      options={customersData}
                      label="Company/Customer ID"
                      name="customer"
                      value={values.customer}
                      getOptionLabel={(option) => `${option.first_name} ${option.last_name}`}
                      getOptionId={(option) => option.id}
                      onChange={(event, selectedOption) => {
                        const id = selectedOption ? selectedOption.id : ""
                        setFieldValue("customer", id);
                      }}
                      error={errors.customer && touched.customer ? errors.customer : null}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <MarginSpace>
                <MapAutocomplete
                  onAddressSelect={(mapAddress) => handleMapAddressSelect(mapAddress, setFieldValue)}
                  setAddress={setAddress}
                  address={address}
                />
              </MarginSpace>

              <MarginSpace>
                <Grid container spacing={3} >
                  <Grid item xs={4} >
                    <InputBox
                      label="Ship ID*"
                      onChange={handleChange}
                      name="ship_id"
                      type="text"
                      disabled={false}
                      value={values.ship_id}
                      error={errors.ship_id && touched.ship_id ? errors.ship_id : null}
                    />
                  </Grid>
                  <Grid item xs={4} >
                    <InputBox
                      label="C/-"
                      onChange={handleChange}
                      name="cperminus"
                      type="text"
                      disabled={false}
                      value={values.cperminus}
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <InputBox
                      label="Address"
                      onChange={handleChange}
                      name="address"
                      type="text"
                      value={values.address}
                      disabled={false}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <MarginSpace>
                <Grid container spacing={3} >
                  <Grid item xs={4} >
                    <InputBox
                      label="Suburb"
                      onChange={handleChange}
                      name="suburbCity"
                      type="text"
                      value={values.suburbCity}
                      disabled={false}
                    />
                  </Grid>
                  <Grid item xs={4} >
                    <InputBox
                      label="Postcode"
                      onChange={handleChange}
                      name="postcode"
                      type="text"
                      value={values.postcode}
                      disabled={false}
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <SelectorComp
                      label="State"
                      onChange={handleChange}
                      options={values.country === "australia" ? AU_STATES : values.country === "new_zealand" ? NZ_STATES : []}
                      value={values.stateRegionType}
                      name={'stateRegionType'}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <MarginSpace>
                <Grid container spacing={2} >
                  <Grid item xs={4} >
                    <SelectorComp
                      label="Timeslot"
                      onChange={handleChange}
                      options={TIMESLOT_REQUIRED}
                      value={values.timeslot_required}
                      name="timeslot_required"
                    />
                  </Grid>
                  <Grid item xs={8} >
                    <InputBox
                      label="Timeslot Booking Information"
                      multiline
                      onChange={handleChange}
                      name="timeslot_booking_info"
                      type="text"
                      disabled={false}
                      value={values.timeslot_booking_info}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <MarginSpace>
                <Grid container spacing={2} >
                  <Grid item xs={6} >
                    <InputBox
                      label="Receiving Hours"
                      onChange={handleChange}
                      name="receivingHours"
                      type="text"
                      disabled={false}
                      value={values.receivingHours}
                    />
                  </Grid>
                  <Grid item xs={6} >
                    <InputBox
                      label="Truck Requirements"
                      onChange={handleChange}
                      name="truck_requirement"
                      type="text"
                      disabled={false}
                      value={values.truck_requirement}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <MarginSpace>
                <Grid container spacing={3} >
                  <Grid item xs={4} >
                    <SelectorComp
                      label="Pallet Restrictions"
                      onChange={handleChange}
                      options={TIMESLOT_REQUIRED}
                      value={values.pallet_restrictions}
                      name="pallet_restrictions"
                    />
                  </Grid>
                  <Grid item xs={4} >
                    <InputBox
                      label="Pallet Restrictions Instructions"
                      onChange={handleChange}
                      name="pallet_restrictions_instructions"
                      type="text"
                      disabled={false}
                      value={values.pallet_restrictions_instructions}
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <InputBox
                      label="Instructions"
                      multiline
                      onChange={handleChange}
                      name="instruction"
                      type="text"
                      disabled={false}
                      value={values.instruction}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>

              <Grid md={12} item>
                <DynamicPalletAccounts palletAccounts={palletAccounts} onPalletAccountsChange={handlePalletAccountsChange} readOnly={false} />
              </Grid>

              <MarginSpace>
                <Grid container spacing={3}>
                  <Grid item xs={6} >
                    <InputBox
                      label="Longitude"
                      onChange={handleChange}
                      name="longitude"
                      type="text"
                      value={values.longitude ?? ""}
                      disabled={false}
                    />
                  </Grid>
                  <Grid item xs={6} >
                    <InputBox
                      label="Latitude"
                      onChange={handleChange}
                      name="latitude"
                      type="text"
                      value={values.latitude ?? ""}
                      disabled={false}
                    />
                  </Grid>
                </Grid>
              </MarginSpace>
              <Divider />
              <ButtonFlex>
                <Button variant="contained" color="default" onClick={() => handleClose(resetForm)} >Cancel</Button>
                <Button variant="contained" color="primary" startIcon={<AddIcon />} type='submit' disabled={isSubmitting}>Create</Button>
              </ButtonFlex>
            </Form>
          </ModalWrapper>
        )}

      </Formik>
    </>
  )
}

export default CreateAddressModal