import { Grid, Typography, Divider, FormControl, InputLabel, Select, MenuItem, makeStyles, Button } from '@material-ui/core'
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { toast } from 'react-toastify'
import { IUserInfo } from '../../../../../../Application/DTOs/UsersDto/UsersDto.type'
import { Driver } from '../../../../Api/Driver/Driver'
import { setLoader } from '../../../../Redux/Loader/actions'
import { COMMISION_RATES_TYPE, COUNTRIES, MOVEMENT_TYPES, USER_ROLES } from '../../../../Types/Constants'
import TextFieldSelectCombo from '../../../Common/TextFieldSelectCombo/TextFieldSelectCombo'
import { IDriverFeeConfig, IDriverJobTypeFee, IFee } from '../../../../../../Application/DTOs/DriverFeeSettingsDto/DriverFeeSettingsDto.types'
import { DriverFeeSettingsReducer } from './DriverFeeSettings.reducer'
import { isEmpty } from 'lodash'
import CheckIcon from '@material-ui/icons/Check';
import { AppState } from '../../../../Redux'
import { getJobTypes } from '../../../../Utilities/FeeSettings'
import SectionHeader from '../../../Common/SectionHeader/SectionHeader'

const useStyles = makeStyles(() => ({
    formControl: {
        minWidth: '100%',
    },
    title: {
        fontWeight: 'bolder'
    },
    updatebtn: {
        color: 'white',
        backgroundColor: 'green',
        '&:hover': {
            backgroundColor: 'green',
        }
    },
}))

const {
    EMPTY_PARK,
    FCL,
    FULL_TRUCK_LOAD,
    LAND_FREIGHT,
    LCL,
    LOOSE_CARGO,
    OTHER,
    RAIL,
    SEA_FREIGHT,
    WHARF,
    ALL
} = MOVEMENT_TYPES

const {
    AUSTRALIA,
    JAPAN,
    PHILIPPINES,
    SINGAPORE
} = COUNTRIES

const {
    FLAT_RATE,
    PERCENTAGE,
    M3
} = COMMISION_RATES_TYPE

const COMMISION_RATES_TYPES_OPTIONS = [
    FLAT_RATE,
    PERCENTAGE,
    M3
]

const driverApi = new Driver()

const generateInitialState = (): IDriverFeeConfig => {
    return Object.values(MOVEMENT_TYPES).reduce<IDriverFeeConfig>((config, movementType) => {
        config[movementType] = getJobTypes(movementType).reduce<IDriverJobTypeFee>((driverJobTypeFee, jobType) => {
            driverJobTypeFee[jobType] = {
                amount: 0,
                type: FLAT_RATE
            }

            return driverJobTypeFee
        }, {})

        return config
    }, {})
}

const initialState: IDriverFeeConfig = generateInitialState()

const {
    ADMIN_USER
} = USER_ROLES

function DriverFeeSettings() {
    const [t] = useTranslation('DriverFreeSettings')
    const user = useSelector((state: AppState) => state.user)
    const isUserAdmin = user.response?.type === ADMIN_USER
    const classes = useStyles()
    const dispatch = useDispatch()
    const [drivers, setDrivers] = useState<IUserInfo[]>([])
    const [selectedDriverId, setSelectedDriverId] = useState<string>('')
    const [country, setCountry] = useState(isUserAdmin ? user.response?.country ?? AUSTRALIA : AUSTRALIA)
    const [movementType, setMovementType] = useState(ALL)
    const [driverFeeConfig, localDispatch] = useReducer(DriverFeeSettingsReducer, initialState)

    const getDrivers = useCallback(
        (country: string) => {
            dispatch(setLoader(true))
            driverApi.getApprovedAndActiveDrivers(country)
                .then(response => {
                    const users: IUserInfo[] = response.data
                    setDrivers(users)
                    dispatch(setLoader(false))
                    setSelectedDriverId('')
                })
                .catch(err => {
                    dispatch(setLoader(false))
                    console.log('err', err)
                    toast.error(t('error_getting_drivers'))
                })

        },
        [dispatch, t],
    )

    const getDriverConfig = useCallback(
        (selectedDriverId: string) => {
            dispatch(setLoader(true))
            driverApi.getDriverFeeConfig(selectedDriverId)
                .then(response => {
                    const config: IDriverFeeConfig = response.data
                    if (isEmpty(config)) {
                        localDispatch({ type: 'SET', payload: initialState })
                    } else {
                        localDispatch({ type: 'SET', payload: config })
                    }
                    dispatch(setLoader(false))
                })
                .catch(err => {
                    dispatch(setLoader(false))
                    console.log('err', err)
                    toast.error(t('error_getting_driver_fee_config'))
                })
        },
        [dispatch, t],
    )

    useEffect(() => {
        getDrivers(country)

    }, [getDrivers, country])

    useEffect(() => {
        if (selectedDriverId !== '')
            getDriverConfig(selectedDriverId)

    }, [getDriverConfig, selectedDriverId])


    const commissionJobTypes = useMemo(() => getJobTypes(movementType).map((JOB_TYPE, i) => {
        const feeValues: IFee = driverFeeConfig[movementType][JOB_TYPE]

        return (
            <Grid key={i} sm={12} md={6} item>
                <TextFieldSelectCombo
                    disabled={selectedDriverId === ''}
                    textPlaceholder={t(JOB_TYPE)}
                    selectPlacholder={t('type')}
                    items={COMMISION_RATES_TYPES_OPTIONS}
                    selectValue={feeValues.type}
                    textValue={String(feeValues.amount)}
                    onTextChange={(e: any) => {
                        const value = Number(e.target.value)

                        if (feeValues.type === PERCENTAGE) {
                            if (value >= 100) {
                                return
                            }
                        }

                        localDispatch({
                            type: 'UPDATE',
                            payload: {
                                amount: value,
                                commissionType: feeValues.type,
                                jobType: JOB_TYPE,
                                movementType
                            }
                        })
                    }}
                    onSelectChange={(e: any) => {
                        localDispatch({
                            type: 'UPDATE',
                            payload: {
                                amount: 0,
                                commissionType: e.target.value,
                                jobType: JOB_TYPE,
                                movementType
                            }
                        })
                    }}
                />
            </Grid>
        )
    }), [selectedDriverId, t, movementType, driverFeeConfig])

    const handleUpdateClick = useCallback(
        () => {
            if (selectedDriverId !== '') {
                dispatch(setLoader(true))
                driverApi.updateDriverFeeConfig(selectedDriverId, driverFeeConfig)
                    .then(() => {
                        toast.success(t('success_updating_driver_fee_config'))
                        dispatch(setLoader(false))
                    })
                    .catch(err => {
                        dispatch(setLoader(false))
                        console.log('err', err)
                        toast.error(t('error_updating_driver_fee_config'))
                    })
            }
        },
        [selectedDriverId, dispatch, t, driverFeeConfig],
    )

    return (
        <>
            <Grid
                container
                direction="column"
                justifyContent="space-between"
                alignItems="stretch"
                spacing={5}
            >
                <SectionHeader subtitle={t("driver_management")} title={t('driver_fee_settings')} />

               
                <Grid item>
                    <Grid
                        container
                        spacing={2}
                    >
                        <Grid md={6} item>
                            {/* <FormControl variant="filled" className={classes.formControl}>
                                <InputLabel style={{ fontWeight: 'bold' }}>{t('country')}</InputLabel>
                                <Select
                                    disabled={isUserAdmin}
                                    value={country}
                                    onChange={(e) => {
                                        localDispatch({ type: 'SET', payload: initialState })
                                        setCountry(e.target.value as string)
                                        setSelectedDriverId('')
                                    }}
                                >
                                    <MenuItem value={AUSTRALIA}>{t(AUSTRALIA)}</MenuItem>
                                    <MenuItem value={JAPAN}>{t(JAPAN)}</MenuItem>
                                    <MenuItem value={PHILIPPINES}>{t(PHILIPPINES)}</MenuItem>
                                    <MenuItem value={SINGAPORE}>{t(SINGAPORE)}</MenuItem>

                                </Select>
                            </FormControl> */}
                        </Grid>
                        <Grid md={6} item>
                            <FormControl variant="filled" className={classes.formControl}>
                                <InputLabel style={{ fontWeight: 'bold' }}>{t('drivers')}</InputLabel>
                                <Select
                                    value={selectedDriverId}
                                    onChange={(e) => setSelectedDriverId(e.target.value as string)}
                                >
                                    {drivers.map(driver => <MenuItem key={driver.id} value={driver.driver?.id}>{`${driver.firstName} ${driver.lastName}`}</MenuItem>)}
                                </Select>
                            </FormControl>
                        </Grid>
                        <Grid md={12} item>
                            <FormControl variant="filled" className={classes.formControl}>
                                <InputLabel style={{ fontWeight: 'bold' }}>{t('movement_type')}</InputLabel>
                                <Select
                                    value={movementType}
                                    onChange={(e) => setMovementType(e.target.value as string)}
                                >
                                    <MenuItem value={ALL}>{t(ALL)}</MenuItem>
                                    <MenuItem value={EMPTY_PARK}>{t(EMPTY_PARK)}</MenuItem>
                                    <MenuItem value={FCL}>{t(FCL)}</MenuItem>
                                    <MenuItem value={FULL_TRUCK_LOAD}>{t(FULL_TRUCK_LOAD)}</MenuItem>
                                    <MenuItem value={LAND_FREIGHT}>{t(LAND_FREIGHT)}</MenuItem>
                                    <MenuItem value={LCL}>{t(LCL)}</MenuItem>
                                    <MenuItem value={LOOSE_CARGO}>{t(LOOSE_CARGO)}</MenuItem>
                                    <MenuItem value={OTHER}>{t(OTHER)}</MenuItem>
                                    <MenuItem value={RAIL}>{t(RAIL)}</MenuItem>
                                    <MenuItem value={SEA_FREIGHT}>{t(SEA_FREIGHT)}</MenuItem>
                                    <MenuItem value={WHARF}>{t(WHARF)}</MenuItem>
                                </Select>
                            </FormControl>
                        </Grid>
                        <Grid md={6} item>
                            {/* GAP */}
                        </Grid>
                        <Grid item md={12}>
                            <Typography className={classes.title}>
                                {t('commission_rates')}
                            </Typography>
                        </Grid>
                        {commissionJobTypes}
                        <Grid item md={12}>
                            <Grid container spacing={2}>
                                <Grid md={3} item>
                                    <Button onClick={handleUpdateClick} startIcon={<CheckIcon />} fullWidth className={classes.updatebtn} variant="contained">
                                        {t('update')}
                                    </Button>
                                </Grid>
                            </Grid>
                        </Grid>
                    </Grid>
                </Grid>
            </Grid>
        </>
    )

}

export default DriverFeeSettings