import {useState, useEffect} from 'react'
import React from 'react'

import axios from 'axios';


import PropTypes from 'prop-types';

//import { useNavigate, useLocation } from 'react-router-dom';
import { Button } from '@mui/material'

import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';

import { DataGrid, GridToolbarContainer, GridActionsCellItem } from '@mui/x-data-grid';
import Snackbar from '@mui/material/Snackbar';
import Alert from '@mui/material/Alert';
import Grid from '@mui/material/Grid';
import Dialog from '@mui/material/Dialog';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContentText from '@mui/material/DialogContentText';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';

import ListFieldApiwoArticle from "./ListFieldApiwoArticle.component"

const baseURL = "http://localhost:8000/api"
const apiURL = "/article/ingrediences/"


  
function EditToolbar(props) {
    const { setTableData, articleId, setOpenAddDialog } = props;

    const handleNewEntryClick = async () => {

        const newValue = { ingredient: {id: -1, name: 'Bitte auswählen'}, percent: null, isNew: true, article: articleId };
        const receivedData = await axios.post(baseURL+"/article/articleIngrediences/"+articleId, {
            newValue, 
        })

        //console.log(receivedData)    
        const newRow = { id: receivedData.data.id, ingredient: {id: -1, name: 'Bitte auswählen'}, percent: receivedData.data.percent, isNew: true, article: receivedData.data.article, position: receivedData.data.position };

        setTableData((oldRows) => [...oldRows, newRow]);
    };

    const handleNewIngredientClick = () => {
        setOpenAddDialog(true);
        /*
        const newValue = { packaging_id: {id: -1, name: 'Bitte auswählen'}, weight: 0, isNew: true, article_id: articleId };
        const receivedData = await axios.post(baseURL+"/article/articleIngrediences/"+articleId, {
            newValue, 
        })

        //console.log(receivedData)    
        const newRow = { id: receivedData.data.id, ingredient: {id: -1, name: 'Bitte auswählen'}, percent: receivedData.data.percent, isNew: true, article: receivedData.data.article, position: receivedData.data.positio };

        setTableData((oldRows) => [...oldRows, newRow]);
        */
    };




    return (
        <GridToolbarContainer>
            <Button color="primary" startIcon={<AddIcon />} onClick={handleNewEntryClick}>
                Neuer Eintrag
            </Button>
            <Button color="primary" startIcon={<AddIcon />} onClick={handleNewIngredientClick}>
                Neue Zutat
            </Button>
        </GridToolbarContainer>
        
    );
}

EditToolbar.propTypes = {
    setTableData: PropTypes.func.isRequired,
    setOpenAddDialog: PropTypes.func.isRequired,
}

const IngredienceDataGrid = (props) => {
    const { articleId } = props;
    
    //list contains all ingrediences
    const [list, setList] = useState([{id: -1, name: '', subIngredients: []}]);
    const [tableData, setTableData] = useState([{id: -1, ingredient: {id: -1, name: ''}, percent: null, article: -1, position: -1}]);
    const [snackbar, setSnackbar] = useState(null);

    const [openAddDialog, setOpenAddDialog] = useState(false);

    const [newIngredient, setNewIngredient] = useState({name: '', allergenes: [], vegan: false, additive: false, vegetarian: false, palmoilfree: true, subIngredients: [], eNumber: ''});

    const columnsIngrediences = [
        {
            field: 'position',
            headerName: 'Pos.',
            width: 50,
            editable: true,
        },
        {
            field: 'ingredient', 
            headerName: 'Name',
            flex: 1,
            type: 'singleSelect',
            valueOptions: list,
            getOptionValue: (value) => value.id,
            getOptionLabel: (value) => {if (value.subIngredients.length === 0) {
                                            return value.name
                                        } else {
                                            return value.name + ' ('+value.subIngredients.map(x => x.name).join(', ')+')'
                                        }
                                       },
            editable: true,
            valueGetter: (params) => {try {return params.row.ingredient.id;} catch {return '';} },
        },
        {
            field: 'percent', 
            headerName: 'Anteil an Gesamtmasse', 
            type: 'number',
            width:170,
            editable: true,
            valueFormatter: (params) => {
                if (params.value == null) {
                  return '';
                }
                return `${params.value} %`;
              },
        },
        {
            field: 'actions',
            type: 'actions',
            headerName: 'Aktionen',
            width: 100,
            cellClassName: 'actions',
            getActions: ({ id }) => {    
              return [
                <GridActionsCellItem
                  icon={<DeleteIcon />}
                  label="Delete"
                  onClick={(e) => handleDeleteClick(id,e)}
                  color="inherit"
                />,
              ];
            },
        }
    ]

    const findId = (idToLookFor) => {
        for (var i = 0; i < list.length; i++) {
            if (list[i].name === idToLookFor) {
                return(list[i].id);
            }
        }
    }

    const handleCloseSnackbar = () => setSnackbar(null);

    //Anscheinend ist es notwendig das event e zu übergeben, ansonsten passieren komische Dinge (kein async, multiple trigger beim rendern etc)
    const handleDeleteClick = async (id,e) => {
        const newData = tableData.filter((row) => row.id !== id);
        //console.log('Delete clicked')
        //console.log(id)
        //console.log(e)
        try {
            const receivedData = await axios.delete(baseURL+"/article/articleIngrediences/"+articleId, {
                data: id, 
            })
            setSnackbar({ children: 'Änderungen erfolgreich gespeichert', severity: 'success' });
            setTableData(newData);
        } catch (error) {
            setSnackbar({ children: error.message, severity: 'error' });
        }
      };
    
    const processRowUpdate = React.useCallback( async (newRow, oldRow) => {
        console.log(newRow)
        const ingredient = list.find(x => x.id === newRow.ingredient);
        const updatedRow = {'id': newRow.id, 'ingredient': ingredient, 'position': newRow.position, 'isNew': false, 'article': articleId, 'percent': newRow.percent};
        const newData = tableData.map((row) => (row.id === newRow.id ? updatedRow : row));

        try {
            const response = await axios.put(baseURL+"/article/articleIngrediences/"+articleId, {
                updatedRow 
            });

            //console.log(response);
            setSnackbar({ children: 'Änderungen erfolgreich gespeichert', severity: 'success' });

            setTableData(newData);
            //onChange(newData);
            return updatedRow;
        } catch (error) {
            setSnackbar({ children: error.message, severity: 'error' });
            return oldRow;
 
        }
      }
    );

    //const handleProcessRowUpdateError = React.useCallback((error) => {
    //    setSnackbar({ children: error.message, severity: 'error' });
    //}, []);
    const handleClose = () => {
    }

    const handleAdd = async() => {
        console.log(newIngredient)

        try {
            const ans = await axios.post(baseURL+"/article/ingrediences/", {
                newIngredient, 
            })
            setSnackbar({ children: 'Änderungen erfolgreich gespeichert', severity: 'success' });
            setOpenAddDialog(false);
            setNewIngredient({name: '', allergenes: [], vegan: false, additive: false, vegetarian: false, palmoilfree: true, subIngredients: [], eNumber: ''});

            setList(list.concat(ans.data));

        } catch (error) {
            setSnackbar({ children: error.message, severity: 'error' });

        }
         
    }


    useEffect(()=>{      
        axios.get(baseURL+apiURL)
             .then((res) => {
                const data = res.data;
                console.log(data);
                setList(data);
            })

        axios.get(baseURL+"/article/articleIngrediences/"+articleId)
            .then((res) => {
                const data = res.data;
                //Add id for each element for displaying in Data Grid
                //data.forEach((item, i) => {
                //    item.id = i + 1;
                //});

                setTableData(data);
                console.log("Fetching ingrediences data")
                console.log(data)
            })

    },[])
    
    return (
        <div style={{ height: 350, width: '100%' }}>
            <DataGrid 
                rows={tableData}
                columns={columnsIngrediences}
                pageSize={10}
                editMode="row"
                //getRowId={(row) => row.internalId}
                processRowUpdate={processRowUpdate}
                //onProcessRowUpdateError={handleProcessRowUpdateError}
                experimentalFeatures={{ newEditingApi: true }}
                components={{
                    Toolbar: EditToolbar,
                }}
                componentsProps={{
                    toolbar: { setTableData, articleId, setOpenAddDialog },
                }}

            />
            <Dialog open={openAddDialog} onClose={handleClose}>
                <DialogTitle>Zutat hinzufügen</DialogTitle>
                <DialogContent>
                <DialogContentText>
                    Füge eine neue Zutat hinzu:
                </DialogContentText>
                    <Grid container spacing={1}>
                            <Grid item xs={12}>
                                <TextField
                                    fullWidth
                                    margin="dense"
                                    id="nameField"
                                    //defaultValue={name != null ? name : ""}
                                    value={newIngredient.name}
                                    onChange={(e) => setNewIngredient({ ...newIngredient, name: e.target.value})}
                                    //error={(article.name.length === 0)}
                                    label="Name"
                                    type="text"
                                    variant="standard"
                                    //onBlur={(e) => handleArticleChangeAPI(e,'name', e.target.value)}
                                />
                            </Grid>
                            <Grid item xs={12}>
                                <ListFieldApiwoArticle 
                                    apiURL="/article/allergenes/" 
                                    titleName="Allergene" 
                                    addName="Zutat"
                                    multiple={true}
                                    value={newIngredient.allergenes} 
                                    onChange={(e) => setNewIngredient({ ...newIngredient, allergenes: e})}
                                    addNew={false}
                                />
                            </Grid>
                            
                            <Grid item xs={12}>
                                <FormControlLabel control={<Checkbox checked={newIngredient.vegan} onChange={(e) => setNewIngredient({ ...newIngredient, vegan: e.target.checked})} />} label="vegan?" />
                                <FormControlLabel control={<Checkbox checked={newIngredient.vegetarian} onChange={(e) => setNewIngredient({ ...newIngredient, vegetarian: e.target.checked})} />} label="vegetarisch?" />
                                <FormControlLabel control={<Checkbox checked={newIngredient.palmoilfree} onChange={(e) => setNewIngredient({ ...newIngredient, palmoilfree: e.target.checked})} />} label="Palmölfrei?" />
                            </Grid>
                            <Grid item xs={12}>
                                <FormControlLabel control={<Checkbox checked={newIngredient.additive} onChange={(e) => setNewIngredient({ ...newIngredient, additive: e.target.checked})} />} label="Zusatzstoff?" />
                            </Grid>
                            <Grid item xs={12}>
                                <TextField
                                    fullWidth
                                    margin="dense"
                                    id="EnumberField"
                                    disabled={!newIngredient.additive}
                                    value={newIngredient.eNumber}
                                    onChange={(e) => setNewIngredient({ ...newIngredient, eNumber: e.target.value})}
                                    error={(newIngredient.eNumber.length === 0 && newIngredient.additive)}
                                    label="E-Nummer"
                                    type="text"
                                    variant="standard"
                                />
                            </Grid>
                            <Grid item xs={12}>
                                <ListFieldApiwoArticle 
                                    apiURL="/article/ingrediences/" 
                                    titleName="Inhaltsstoffe" 
                                    addName="Zutat"
                                    multiple={true}
                                    value={newIngredient.subIngredients} 
                                    onChange={(e) => setNewIngredient({ ...newIngredient, subIngredients: e})}
                                />
                            </Grid>
                    </Grid>
                </DialogContent>
                <DialogActions>
                <Button onClick={() => setOpenAddDialog(false)}>Abbrechen</Button>
                <Button onClick={handleAdd}>Hinzufügen</Button>
                </DialogActions>
            </Dialog>
            {!!snackbar && (
                <Snackbar
                open
                anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
                onClose={handleCloseSnackbar}
                autoHideDuration={6000}
                >
                <Alert {...snackbar} onClose={handleCloseSnackbar} />
                </Snackbar>
            )}
        </div>
    );
}

export default IngredienceDataGrid
