import { Button, Dialog, DialogActions, InputAdornment, DialogContent, DialogTitle, Grid, TextField, Typography, makeStyles, Select, FormControl, InputLabel, MenuItem } from "@material-ui/core";
import { useTranslation } from "react-i18next";
import { IBidDialogProps } from "./BidDialog.types";
import MonetizationOnIcon from '@material-ui/icons/MonetizationOn';
import { Job } from "../../../Api/Job/Job";
import { useCallback, useEffect, useMemo, useState } from "react";
import { AppState } from "../../../Redux";
import { useDispatch, useSelector } from "react-redux";
import { toast } from "react-toastify";
import { USER_ROLES, JOB_CLASSIFICATION, MOVEMENT_TYPES } from "../../../Types/Constants";
import SingleAutocomplete from "../../Common/SingleAutocomplete/SingleAutocomplete";
import { Company } from "../../../Api/Company/Company";
import { setLoader } from "../../../Redux/Loader/actions";
import { ICompanyInfo } from "../../../../../Application/DTOs/CompanyDto/CompanyDto.type";
import { IAutocompleteOption } from "../../Common/types";
import { Driver } from "../../../Api/Driver/Driver";
import { IUserInfo } from "../../../../../Application/DTOs/UsersDto/UsersDto.type";
import capitalize from "capitalize";
import TextFieldsIcon from '@material-ui/icons/TextFields';
import { CURRENCIES } from "../../../Types/Currencies";
import { isFloat, isNonNumeric } from "../../../Utilities/Regex";
const jobApi = new Job()

const companyApi = new Company()

const driverApi = new Driver()

const {
    SUPER_ADMIN,
    ADMIN_USER,
    COMPANY,
    DRIVER
} = USER_ROLES

const { SEA_FREIGHT, TRANSPORT } = JOB_CLASSIFICATION

const { LCL } = MOVEMENT_TYPES

const useStyles = makeStyles(() => ({
    formControl: {
        minWidth: '100%',
    },
}))

const companiesToOptions = (company: ICompanyInfo): IAutocompleteOption => ({
    label: company.companyName,
    value: company.user?.id
})

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

function BidDialog(props: IBidDialogProps) {
    const [t] = useTranslation('BidDialog')
    const dispatch = useDispatch()

    const user = useSelector((state: AppState) => state.user)
    const isAdmin = [SUPER_ADMIN, ADMIN_USER].includes(user.response?.type ?? '')
    const isUserAdmin = user.response?.type === ADMIN_USER

    const classes = useStyles()

    const [bidAmount, setBidAmount] = useState('')
    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 [waitTime, setWaitTime] = useState('')
    const [waitTimeCharge, setWaitTimeCharge] = useState('')
    const [currencyCode, setCurrencyCode] = useState(CURRENCIES['USD'].code)
    const [totalFreightCurrencyCode, setTotalFreightCurrencyCode] = useState(CURRENCIES['USD'].code)
    const [originCurrencyCode, setOriginCurrencyCode] = useState(CURRENCIES['USD'].code)
    const [destinationCurrencyCode, setDestinationCurrencyCode] = useState(CURRENCIES['USD'].code)
    const [totalFreight, setTotalFreight] = useState('')
    const [originCharges, setOriginCharges] = useState('')
    const [destinationCharges, setDestinationCharges] = useState('')

    const { selectedJob } = props

    const handleBidClick = () => {
        if (selectedJob) {
            let userId: any

            if (isAdmin) {
                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
                }
            } else {
                if (user.response)
                    userId = user.response?.id
                else
                    return
            }

            if(bidAmount === '') {
                toast.warning(t('bid_amount_is_required'))
                return
            } else if(isNonNumeric(bidAmount)) {
                toast.warning(t('invalid_bid_amount'))
                return
            } else if(isFloat(waitTime)) {
                toast.warning(t('invalid_wait_time'))
                return
            }

            jobApi.bid({
                userId,
                jobId: selectedJob.id,
                bidAmount: parseFloat(parseFloat(bidAmount).toFixed(2)),
                waitTime: Number(waitTime),
                waitTimeCharge: parseFloat(parseFloat(waitTimeCharge).toFixed(2)),
                currencyCode,
                totalFreight: Number(totalFreight),
                destinationCharges: parseFloat(parseFloat(destinationCharges).toFixed(2)),
                destinationCurrencyCode,
                originCharges: parseFloat(parseFloat(originCharges).toFixed(2)),
                originCurrencyCode,
                totalFreightCurrencyCode
            })
                .then(() => {
                    toast.success(t('bidding_successfull'))
                    if (props.onDone) props.onDone()
                    props.handleClose()
                })
                .catch((err :any) => {
                    console.log('err', err)
                    toast.error(t(err.response?.data?.error_code || 'error_bidding_job'))
                })
        }
    }

    const getCompanies = useCallback(
        (country?: string) => {
            dispatch(setLoader(true))
            companyApi.getAll(country)
                .then((response) => {
                    const companies: ICompanyInfo[] = response.data
                    setCompanies(companies.map(companiesToOptions))
                    dispatch(setLoader(false))
                })
                .catch(err => {
                    console.log('err', err)
                    dispatch(setLoader(false))
                    toast.error(t('error_getting_companies'))
                })
        },
        [dispatch, t],
    )

    const getDrivers = useCallback(
        (country?: string) => {
            dispatch(setLoader(true))
            driverApi.getAll(country)
                .then((response) => {
                    const users: IUserInfo[] = response.data

                    setDrivers(users.map(driverToOptions))

                    dispatch(setLoader(false))
                })
                .catch(err => {
                    console.log('err', err)
                    dispatch(setLoader(false))
                    toast.error(t('error_getting_drivers'))
                })
        },
        [dispatch, t],
    )

    useEffect(() => {
        setBidAmount('')

        const country = isUserAdmin ? user.response?.country : undefined

        if (props.open) {
            if (isAdmin) {
                getCompanies(country)
                getDrivers(country)
            }
        } else {
            setCompanies([])
            setDrivers([])
            setSelectedUserType('')
            setSelectedDriver(null)
            setSelectedCompany(null)
        }
    }, [props.open, isAdmin, getCompanies, isUserAdmin, user, getDrivers])

    const currencyOptions = useMemo(() => Object.values(CURRENCIES).map((currency, i) => <MenuItem key={i} value={currency.code} >{t(currency.code)} - {currency.symbol}</MenuItem>), [t])

    return (
        <>
            <Dialog maxWidth="sm" fullWidth open={props.open} onClose={props.handleClose}>
                <DialogTitle>
                    <Typography>
                        {t('bid_on_job')}
                    </Typography>
                </DialogTitle>
                <DialogContent dividers>
                    <Grid
                        container
                        spacing={3}
                    >
                        {
                            isAdmin
                                ? <>
                                    <Grid item sm={12}>
                                        <FormControl variant="filled" className={classes.formControl}>
                                            <InputLabel style={{ fontWeight: 'bold' }}>{t('select_user_type')}</InputLabel>
                                            <Select
                                                value={selectedUserType}
                                                onChange={(e) => {
                                                    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)}

                                                />
                                            </Grid>
                                            : null
                                    }
                                    {
                                        selectedUserType === DRIVER
                                            ? <Grid item sm={12}>
                                                <SingleAutocomplete
                                                    value={selectedDriver}
                                                    label={t('driver')}
                                                    options={drivers}
                                                    onChange={(value) => setSelectedDriver(value)}
                                                />
                                            </Grid>
                                            : null
                                    }
                                </>
                                : null
                        }
                        {
                            selectedJob?.job_classification === SEA_FREIGHT && selectedJob.movement_type === LCL
                            ?   <>
                                    <Grid item sm={3}>
                                        <FormControl variant="filled" className={classes.formControl}>
                                            <InputLabel style={{ fontWeight: 'bold' }}>{t('currency')}</InputLabel>
                                            <Select
                                                value={totalFreightCurrencyCode}
                                                onChange={(e) => {
                                                    setTotalFreightCurrencyCode(e.target.value as string)
                                                }}
                                            >
                                                {currencyOptions}
                                            </Select>
                                        </FormControl>
                                    </Grid>
                                    <Grid item md={9}>
                                        <TextField
                                            value={totalFreight}
                                            onChange={e => setTotalFreight(e.target.value)}
                                            fullWidth
                                            type="number"
                                            variant="outlined"
                                            label={t('total_freight')}
                                            InputLabelProps={{
                                                style: {
                                                    fontWeight: 'bold'
                                                }
                                            }}
                                            InputProps={{
                                                endAdornment: (
                                                    <InputAdornment position="end">
                                                        <MonetizationOnIcon />
                                                    </InputAdornment>
                                                )
                                            }}
                                        />
                                    </Grid>
                                    <Grid item sm={3}>
                                        <FormControl variant="filled" className={classes.formControl}>
                                            <InputLabel style={{ fontWeight: 'bold' }}>{t('currency')}</InputLabel>
                                            <Select
                                                value={originCurrencyCode}
                                                onChange={(e) => {
                                                    setOriginCurrencyCode(e.target.value as string)
                                                }}
                                            >
                                                {currencyOptions}
                                            </Select>
                                        </FormControl>
                                    </Grid>
                                    <Grid item md={9}>
                                        <TextField
                                            value={originCharges}
                                            onChange={e => setOriginCharges(e.target.value)}
                                            fullWidth
                                            type="number"
                                            variant="outlined"
                                            label={t('origin_charges')}
                                            InputLabelProps={{
                                                style: {
                                                    fontWeight: 'bold'
                                                }
                                            }}
                                            InputProps={{
                                                endAdornment: (
                                                    <InputAdornment position="end">
                                                        <MonetizationOnIcon />
                                                    </InputAdornment>
                                                )
                                            }}
                                        />
                                    </Grid>
                                </>
                            : null
                        }
                        {
                            selectedJob?.has_destination_charges && selectedJob.movement_type === LCL
                                ? <>
                                    <Grid item sm={3}>
                                        <FormControl variant="filled" className={classes.formControl}>
                                            <InputLabel style={{ fontWeight: 'bold' }}>{t('currency')}</InputLabel>
                                            <Select
                                                value={destinationCurrencyCode}
                                                onChange={(e) => {
                                                    setDestinationCurrencyCode(e.target.value as string)
                                                }}
                                            >
                                                {currencyOptions}
                                            </Select>
                                        </FormControl>
                                    </Grid>
                                    <Grid item md={9}>
                                        <TextField
                                            value={destinationCharges}
                                            onChange={e => setDestinationCharges(e.target.value)}
                                            fullWidth
                                            type="number"
                                            variant="outlined"
                                            label={t('destination_charges')}
                                            InputLabelProps={{
                                                style: {
                                                    fontWeight: 'bold'
                                                }
                                            }}
                                            InputProps={{
                                                endAdornment: (
                                                    <InputAdornment position="end">
                                                        <MonetizationOnIcon />
                                                    </InputAdornment>
                                                )
                                            }}
                                        />
                                    </Grid>
                                </>
                                : null
                        }

                        {
                            selectedJob?.movement_type !== LCL
                            ?   <>
                        <Grid item md={12}>
                            <TextField
                                value={bidAmount}
                                onChange={(e) => setBidAmount(e.target.value)}
                                fullWidth
                                variant="outlined"
                                label={t('enter_bid_amount')}
                                InputLabelProps={{
                                    style: {
                                        fontWeight: 'bold'
                                    }
                                }}
                                InputProps={{
                                    endAdornment: (
                                        <InputAdornment position="end">
                                            <MonetizationOnIcon />
                                        </InputAdornment>
                                    )
                                }}
                            />
                        </Grid>
                        <Grid item md={12}>
                            <TextField
                                value={waitTime}
                                onChange={(e) => setWaitTime(e.target.value)}
                                fullWidth
                                type="number"
                                variant="outlined"
                                label={t('waiting_time')}
                                InputLabelProps={{
                                    style: {
                                        fontWeight: 'bold'
                                    }
                                }}
                                InputProps={{
                                    endAdornment: (
                                        <InputAdornment position="end">
                                            <TextFieldsIcon />
                                        </InputAdornment>
                                    )
                                }}
                            />
                        </Grid>
                        <Grid item md={12}>
                            <TextField
                                value={waitTimeCharge}
                                onChange={(e) => setWaitTimeCharge(e.target.value)}
                                fullWidth
                                variant="outlined"
                                label={t('waiting_time_charge')}
                                InputLabelProps={{
                                    style: {
                                        fontWeight: 'bold'
                                    }
                                }}
                                InputProps={{
                                    endAdornment: (
                                        <InputAdornment position="end">
                                            <TextFieldsIcon />
                                        </InputAdornment>
                                    )
                                }}
                            />
                        </Grid>

                                </>
                            : null
                        }

                    </Grid>
                </DialogContent>
                <DialogActions>
                    <Button onClick={handleBidClick} variant="contained" color="primary">
                        {t('bid')}
                    </Button>
                </DialogActions>
            </Dialog>
        </>
    )
}

export default BidDialog