import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography, Grid, FormControl, Select, InputLabel, MenuItem, TextField, FormLabel, Radio, RadioGroup, FormControlLabel } from "@material-ui/core";
import capitalize from "capitalize";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { toast } from "react-toastify";
import { ICompanyInfo, ICompanyInfoRates } from "../../../../../../../Application/DTOs/CompanyDto/CompanyDto.type";
import { IUserInfo } from "../../../../../../../Application/DTOs/UsersDto/UsersDto.type";
import { Company } from "../../../../../Api/Company/Company";
import { Driver } from "../../../../../Api/Driver/Driver";
import { AppState } from "../../../../../Redux";
import { setLoader } from "../../../../../Redux/Loader/actions";
import { USER_ROLES } from "../../../../../Types/Constants";
import SingleAutocomplete from "../../../../Common/SingleAutocomplete/SingleAutocomplete";
import { IAutocompleteOption } from "../../../../Common/types";
import { ISelectUserDialogProps } from "./SelectUserDialog.types";
import { AdminSettings } from "../../../../../Api/AdminSettings/AdminSettings"
import { IRatesManagement } from "../../../../../../../Application/Models/RatesManagementSettingsModel/RatesManagement.types";
import { isNil } from 'lodash';

const {
    COMPANY,
    DRIVER
} = USER_ROLES

const companyApi = new Company()
const driverApi = new Driver()
const adminSettingApi = new AdminSettings()




export const driverToOptions = (user: IUserInfo): IAutocompleteOption => ({
    label: capitalize.words(`${user.driver?.first_name ?? ''} ${user.driver?.last_name ?? ''}`),
    value: user.id
})

function SelectUserDialog(props: ISelectUserDialogProps) {
    const [t] = useTranslation('SelectUserDialog')
    const { open, handleClose, onSelectUserCallback, isAdmin, companyId, allocate = false, selectedJob } = props

    const user = useSelector((state: AppState) => state.user)
    const dispatch = useDispatch()

    const [companies, setCompanies] = useState<IAutocompleteOption[]>([])
    const [drivers, setDrivers] = useState<IAutocompleteOption[]>([])
    const [selectedDriver, setSelectedDriver] = useState<IAutocompleteOption | null>(null)
    const [selectedCompany, setSelectedCompany] = useState<IAutocompleteOption | null>(null)
    const [selectedUserType, setSelectedUserType] = useState<typeof DRIVER | typeof COMPANY | ''>('')
    const [sellPrice, setSellPrice] = useState('');
    const [buyPrice, setBuyPrice] = useState('');
    const [temperature, setTemperature] = useState<string>('');
    const [configurationType, setConfigurationType] = useState('');
    const [containerType, setContainerType] = useState('');
    const [selectedRates, setSelectedRates] = useState<IAutocompleteOption | null>(null)
    const [ratesDropdown, setRatesDropdown] = useState([])

    let compId = isAdmin ? companyId : user.response?.company?.id


    const getRelatedDrivers = useCallback(
        () => {

            driverApi.getRelatedDrivers(compId ?? '')
                .then((response) => {
                    const users: IUserInfo[] = response.data

                    setDrivers(users.map(driverToOptions))
                    dispatch(setLoader(false))
                })
                .catch((err: any) => {
                    console.log('err', err)
                    toast.error(t('error_getting_related_drivers'))
                    dispatch(setLoader(false))
                })
        },
        [dispatch, t, compId]
    )
    const checkIfEmpty = (data: any) => {
        return (data === '' || isNil(data));
    }
    const getWharfRates = (rates: any) => {
        if (rates) {
            const buy = rates[0]['buyRate']
            const sell = rates[0]['sellRate']
            return { buy_rate: buy, sell_rate: sell }
        } else {
            return { buy_rate: 0, sell_rate: 0 }
        }
    }

    const getRatesConnnect = (confType: any, companyID: any, deliver_address_id: any) => {
        return adminSettingApi.getRates(
            {
                posting_company: selectedJob?.company_id,
                transport_company: companyID,
                movement_type: selectedJob?.movement_type,
                temperature: temperature,
                pick_up_address_id: selectedJob?.pickup_address_id,
                deliver_address_id: deliver_address_id,
                is_default: false,
                configuration_type: confType,
                container_type: configurationType == 'wharf' ? selectedJob.job_type : '',
                state_type: selectedJob?.deliver_to_address?.state_type || ''
            }
        )
            .then(async (response) => {
                const ratesData = response.data as IRatesManagement;
                let returnable: any = false
                if (deliver_address_id != '') {

                    if (configurationType == 'wharf') {
                        returnable = { ...ratesData, rates: getWharfRates(ratesData.rates) }
                    }
                    else {
                        if (ratesData.rates) {
                            returnable = { ...ratesData, rates: getMapping(ratesData.rates) }
                        }
                    }
                } else {

                    if (ratesData.rates) {
                        let state_selected = 'interstate'
                        if (selectedJob.deliver_to_address.state_type == 'inner_metro') {
                            state_selected = 'metroInner'
                        } else {
                            state_selected = 'metroOuter'
                        }

                        const filtered_value = ratesData.rates[0][state_selected]
                        const remap = await getMapping(filtered_value)

                        returnable = { ...ratesData, rates: remap }
                    }

                }
                return returnable

            })
            .catch((err: any) => {
                console.log('err', err);
                toast.error(t('error_getting_config'));
                return false
            });
    }
    const getRatesPerCompany = async (companyID: any) => {
        let confType = 'single'
        if (temperature && selectedJob) {
            if (selectedJob && selectedJob.movement_type == 'wharf') {
                setContainerType(selectedJob['job_type'])
                setConfigurationType('wharf')
                confType = 'wharf'
            } else {
                if (!checkIfEmpty(selectedJob.delivery_address_id)) {
                    setConfigurationType('single')
                    confType = 'single'


                }
                else {
                    setConfigurationType('multiple')
                    confType = 'multiple'

                }

            }
            if (selectedJob.pickup_address_id) {
                let ratesCon = await getRatesConnnect(confType, companyID, selectedJob.delivery_address_id)
                if (ratesCon != false) {
                    return ratesCon
                } else {

                    return await getRatesConnnect('multiple', companyID, '')
                }
            }
        }
    }

    const computeRate = (company: any, type: any) => {
        if (company && company.data) {
            const ratesToCheck = type == 'buy_rate' ? 'fuel_surcharge_buy' : 'fuel_surcharge_sell'
            const surcharge = company.data.hasOwnProperty(ratesToCheck) ? company.data[ratesToCheck] : 0
            const ratesList = company.data ? company.data.rates : [{id:1, buy_rate: 0, sell_rate: 0 }]
            const rate = getMapping([ratesList])[type]
            const surPercent = computePercentage(rate, surcharge)
            return surPercent + parseFloat(rate)
        }
        else {
            return 0
        }
    }
    const companiesToOptions = (company: ICompanyInfoRates): IAutocompleteOption => ({
        label: company.companyName + " - $" + computeRate(company, 'sell_rate').toString() as string,
        value: company.user?.id,
        company_id: company.id,
        data: company.data
    })

    const setRelatedCompany = () => {
        if (temperature != '') {
            companyApi.getRelatedCompanies(String(compId), user.response?.company?.country ?? '')
                .then(async (response) => {
                    dispatch(setLoader(false))
                    let companies: ICompanyInfoRates[] = response.data
                    for (let index = 0; index < companies.length; index++) {
                        companies[index].data = await getRatesPerCompany(companies[index].id)
                    }
                    setCompanies(companies.map<IAutocompleteOption>(companiesToOptions))
                })
                .catch((err: any) => {
                    console.log('err', err)
                    dispatch(setLoader(false))
                })
        }
    }
    function computePercentage(percent: number = 0, total: number = 0): number {
        return Math.round((isNaN(percent) ? 0 : percent / 100) * (isNaN(total) ? 0 : total)) as number
    }
    const clearData = () => {
        setSelectedDriver(null)
        setSelectedCompany(null)
        setSelectedUserType('')
        setSellPrice('')
        setBuyPrice('')
        setTemperature('')
        setConfigurationType('')
        setContainerType('')
        setCompanies([])
        setDrivers([])

    }
    useEffect(() => {
        if (open) {
            getRelatedDrivers()
        } else {
            clearData()
        }
    }, [open, getRelatedDrivers])


    const getMapping = (ratesData: any) => {
      
        let quant_get = 1
        if (selectedJob['packages_type'] && selectedJob['packages_type'].length > 0) {
            quant_get = selectedJob['packages_type'][0]['quantity'] as number
        }
        let frates = ratesData.find((i: any) => i.id == quant_get);
        return frates
    }
    const setlabels = (label: any, data: any, fuel_surcharge_buy: any, fuel_surcharge_sell: any) => {
        return { label: t(label), value: label, data: data, fuel_surcharge_buy: fuel_surcharge_buy, fuel_surcharge_sell: fuel_surcharge_sell }
    }
    useEffect(() => {
        if (temperature != '') {
            setSelectedCompany(null)
            setBuyPrice('0')
            setSellPrice('0')
            setRelatedCompany()
        }
    }, [temperature])


    const useDefaultConfig = () => {

        adminSettingApi.getRates(
            {
                posting_company: '',
                transport_company: '',
                movement_type: '',
                temperature: '',
                pick_up_address_id: '',
                deliver_address_id: '',
                is_default: true,
                configuration_type: configurationType,
                container_type: containerType

            }
        )
            .then((response) => {
                const ratesData = response.data as IRatesManagement;

                if (ratesData.rates) {
                    let quant_get = 0;
                    if (selectedJob['packages_type'].length > 0) {
                        quant_get = selectedJob['packages_type'][0]['quantity']
                    }
                    let rates = ratesData.rates.find(i => i.id === quant_get);
                    setBuyPrice((computePercentage(parseFloat(ratesData.fuel_surcharge_buy || 0), parseFloat(rates.buy_rate || 0)) + parseFloat(rates.buy_rate || 0)).toString())
                    setSellPrice((computePercentage(parseFloat(ratesData.fuel_surcharge_sell || 0), parseFloat(rates.sell_rate || 0)) + parseFloat(rates.sell_rate || 0)).toString())

                } else {
                    setBuyPrice('0')
                    setSellPrice('0')
                }
                dispatch(setLoader(false));
            })
            .catch((err: any) => {
                console.log('err', err);
                toast.error(t('error_getting_config'));
                dispatch(setLoader(false));
            });
    }




    const handleAllocateClick = () => {
        let userId: any
        if (buyPrice === '') {
            toast.warn(t('buy_price_required'));
            return;
        }
        if (sellPrice === '') {
            toast.warn(t('sell_price_required'));
            return;
        }
        if (selectedUserType === COMPANY) {
            if (selectedCompany) {
                userId = selectedCompany.value
            } else {
                toast.warn(t('select_a_company'))
                return
            }
        } else if (selectedUserType === DRIVER) {
            if (selectedDriver) {
                userId = selectedDriver.value
            } else {
                toast.warn(t('select_a_driver'))
                return
            }
        }
        else {
            return
        }

        if (onSelectUserCallback)
            onSelectUserCallback(userId, sellPrice, buyPrice, temperature)
    }
    const handleRatesChange = (value: any) => {

        if (value) {
            const ratesData = value.data
            const rates = ratesData.rates
            setBuyPrice((computePercentage(parseFloat(ratesData.fuel_surcharge_buy || 0), parseFloat(rates ? rates.buy_rate : 0)) + parseFloat(rates ? rates.buy_rate : 0)).toString())
            setSellPrice((computePercentage(parseFloat(ratesData.fuel_surcharge_sell || 0), parseFloat(rates ? rates.sell_rate : 0)) + parseFloat(rates ? rates.sell_rate : 0)).toString())
        }

    }
    return (
        <>
            <Dialog maxWidth="sm" fullWidth open={open} onClose={handleClose}>
                <DialogTitle>
                    <Typography>
                        {t('select_user_to_allocate')}
                    </Typography>
                </DialogTitle>
                <DialogContent dividers>
                    <Grid
                        container
                        spacing={2}
                    >
                        <Grid item sm={12}>
                            <FormControl>
                                <FormLabel id="demo-radio-buttons-group-label">{t('temperature')}</FormLabel>
                                <RadioGroup
                                    aria-labelledby="demo-radio-buttons-group-label"
                                    value={temperature ?? " "}
                                    name="radio-buttons-group"
                                    onChange={(e) => {
                                        setTemperature(e.target.value)

                                    }}>
                                    <FormControlLabel value="ambient" control={<Radio />} label={t('ambient')} />
                                    <FormControlLabel value="chilled" control={<Radio />} label={t('chilled')} />
                                    <FormControlLabel value="frozen" control={<Radio />} label={t('frozen')} />
                                </RadioGroup>
                            </FormControl>
                        </Grid>
                        <Grid item sm={12}>
                            <FormControl variant="filled" style={{ minWidth: '100%' }}>
                                <InputLabel style={{ fontWeight: 'bold' }}>{t('select_user_type')}</InputLabel>
                                <Select
                                    value={selectedUserType}
                                    onChange={(e) => {
                                        // getRelatedCompanies()
                                        setRelatedCompany()
                                        setSelectedUserType(e.target.value as string)
                                        setSelectedDriver(null)
                                        setSelectedCompany(null)
                                    }}
                                >
                                    <MenuItem value={DRIVER}>{t(DRIVER)}</MenuItem>
                                    <MenuItem value={COMPANY}>{t(COMPANY)}</MenuItem>
                                </Select>
                            </FormControl>
                        </Grid>
                        {
                            selectedUserType === COMPANY
                                ? <Grid item sm={12}>
                                    <SingleAutocomplete
                                        value={selectedCompany}
                                        label={t('company')}
                                        options={companies}
                                        onChange={(value) => {
                                            setSelectedCompany(value)
                                            handleRatesChange(value)
                                        }
                                        }
                                    />
                                </Grid>
                                : null
                        }
                        {
                            selectedUserType === DRIVER
                                ? <Grid item sm={12}>
                                    <SingleAutocomplete
                                        value={selectedDriver}
                                        label={t('driver')}
                                        options={drivers}
                                        onChange={(value) => setSelectedDriver(value)}
                                    />
                                </Grid>
                                : null
                        }
                        {/* <Grid item sm={12}>
                                    <SingleAutocomplete
                                        value={selectedRates}
                                        label="Rates"
                                        options={ratesDropdown}
                                        onChange={(value) => handleRatesChange(value)}
                                
                                    />
                        </Grid> */}

                        <Grid item sm={12}>

                            <TextField
                                value={sellPrice}
                                // disabled
                                onChange={(e) => setSellPrice(e.target.value)}
                                label={t('sell_price')}
                                fullWidth
                                type="number"
                                variant="outlined"
                                InputLabelProps={{
                                    style: {
                                        fontWeight: 'bold',
                                    },
                                }}
                            />
                        </Grid>
                        {isAdmin ?
                            <Grid item sm={12}>
                                <TextField
                                    value={buyPrice}
                                    // disabled
                                    onChange={(e) => setBuyPrice(e.target.value)}
                                    label={t('buy_price')}
                                    fullWidth
                                    type="number"
                                    variant="outlined"
                                    InputLabelProps={{
                                        style: {
                                            fontWeight: 'bold',
                                        },
                                    }}
                                />
                            </Grid>
                            : null}

                    </Grid>
                </DialogContent>
                <DialogActions>
                    {
                        (allocate) ? <Button onClick={useDefaultConfig} variant="contained" color="default">{t('use_default_config')}</Button> : null
                    }

                    <Button onClick={handleAllocateClick} variant="contained" color="primary">
                        {
                            allocate ? t('allocate') : t('create_n_allocate_job')
                        }
                    </Button>
                </DialogActions>
            </Dialog>
        </>
    )
}


export default SelectUserDialog