import React from 'react';
import Modularity from 'modularity-front';
import {Row,CardTitle,Button,Col,Card} from 'react-materialize';

import Modules from '../Modules/index.js';

import FilterModule from '../Modules/FilterModule.js';

import './ListModule.css';

let {
	Table,
	Pagination,
    Form
} = Modules;

let Module = Modularity.Module;

let pTimeout = (time, item) => {
    return new Promise((res,rej) => {
        setTimeout(() => res(item), time);
    });
}
class ListModule extends Modularity.Module {
	constructor(props) {
		super(props);
		this.state = {
            page: 1,
            data: [],
            totalPages: 1,
            showForm: false,
            model: {},
            mode: 0,
            formButton: "Add" 
		}

        this.service.onUpdate(() => this.serviceUpdate(this.state.page));
        this.serviceUpdate(this.state.page);

        let route = this.RoutingSystem.getRoute().url;
        if(route.endsWith("/add")) {
            pTimeout(1000).then(() => this.showAddForm());
        }
        console.log("ROUTE ", route);
	}
	   
    serviceUpdate(page = 1) {
        let Service = this.service.value;
        
        if(!Service.count)
            return;

        let perPage = this.perPage.value;
        
        return Service.count().then(([{counter}]) => {
            let totalPages = parseInt((counter / perPage) + 0.999);
            page = page <= totalPages ? page : totalPages; 
            this.setState({totalPages, page});
            return Service.getPage(page, perPage);
        })
        .then((data) => {
            this.setState({data});
        }).catch((e) => console.log(e));
    }

    setFilters(filters) {
        this.onFilters.set(filters);
    }

    pageChanged(v) {
        this.serviceUpdate(v);
    }

    update() {
        let data = this.state.formData;
        let Service = this.service.value;
        if(!Service.count || !data)
            return;
        for(var i in data) if(data[i] === "None")data[i] = null;
        Service.update(data.id, data).then((res) => 
            this.serviceUpdate(this.state.page).then(() => this.setState({
                showForm: false,
            }))
        ).catch((e) => window.Materialize ? window.Materialize.toast('Can not update!', 5000) : window.M.toast({html: 'Can not update!', displayLength: 5000}))
    }

    add() {
        let data = this.state.formData;
        let Service = this.service.value;
        if(!Service.count || !data)
            return;

        delete data.id;
        Service.add(data).then((res) => 
            this.serviceUpdate(this.state.page)
        ).then(() => this.setState({
            showForm: false,
        })).catch((e) => window.Materialize ? window.Materialize.toast('Can not Add!', 5000) : window.M.toast({html: 'Can not Add!', displayLength: 5000}))
    }

    rowEdit(row) {
        if(!row) return;
        let Service = this.service.value;
        if(Service.update && row.id)
            Service.update(row.id, row).then(() => this.serviceUpdate(this.state.page)).catch((e) => {
                window.Materialize.toast('Can not Edit!', 5000);
                this.forceUpdate();
            });
    }

    _rowEdited(row){
        if(!row) return;
        let headers = (this.FormHeaders.value);
        let mod = this.prepareForm(headers, row);

        this.setState({
            showForm: true,
            model : mod,
            mode: 1,
            formButton: 'Edit'
        });
    }

    _rowDeleted(row){
        if(!row) return;
        let Service = this.service.value;
        if(Service.delete && row.id)
            Service.delete(row.id).then(() => this.serviceUpdate(this.state.page));
    }
	handleClick() {
		// console.log("added");
	}

    prepareForm(headers, row = {}) {
        let mod = {};
        // console.log(headers);
        for (let i in headers) {
            if(!headers[i])continue;
            //if(headers[i].fieldName === "id") continue;
            mod[headers[i].Name || headers[i].fieldName] = {
                type:"text",
                placeholder:i,
                columns: "col s12  l6 xl4",
                value: row[i],
                filter: headers[i].filter
            };
        }
        return mod;
    }

    showAddForm() {
        let headers = (this.FormHeaders.value);
        // add Required !
        let mod = this.prepareForm(headers);
        this.setState({
            showForm: true,
            model : mod,
            mode: 0,
            formButton: 'Add'
        });
    }

	render() {
        let page     = this.state.page,
            totalPages = this.state.totalPages,
            data  = this.state.data;
           
     

        let TableView = 
                <Row style={{display: 'flex'}} key={'Table'}>
                    <Col s={2}  style={this.props.filterStyle} className={this.props.filterClassName}>
                        <FilterModule Inputs={this.FilterInput.value} Filters={(filters) => this.setFilters(filters)}/>
                    </Col>
                    <Col s={10}>
                        <Table  TableHeaders={this.TableHeaders.value} TableData={data} 
                                TableClass={this.TableClass.value} LiveEdit={this.LiveEdit.value}
                                EditedRow={(v) => this.rowEdit(v)}  onEdit={(v) => this._rowEdited(v)} onDelete={(v) => this._rowDeleted(v)}/>
                        <Row>
                            <Col offset="s10" >
                            <Button onClick={() => this.showAddForm()}>Add</Button>
                            </Col>
                        </Row>
                        <Pagination selected={page} lastPage={totalPages} onPage={(v) => this.pageChanged(v)} />
                    </Col>
                </Row>;
        let FormView = 
        <Row key={'Form'}>
            <Col s={12}>
                <Form FormInputs={this.state.model} button={this.state.formButton} 
                formData={(formData) => this.setState({formData})}
                className={'AdminDataForm'}>
                </Form>
                <Button onClick={(data) => this.state.mode ? this.update() : this.add()}>Save</Button>
            </Col>
        </Row>;

		return [this.state.showForm ? FormView : TableView,super.render()];
				    
	}
}


ListModule.Inputs = {
    service: {
        type: Module.Types.Object,
        defaultValue: {}
    },
	perPage: {
		type: Module.Types.Number,
        defaultValue: 2
	},
    TableHeaders:{
        type: Module.Types.Object,
        defaultValue:{
            "Id" : "id",
            "Name" : "name",
            "Value": "price"
           }
    },
    FormHeaders:{
        type: Module.Types.Object,
        defaultValue:{
            "Id" : "id",
            "Name" : "name",
            "Value": "price"
           }
    },
    TableClass:{
        type: Module.Types.Text,
        defaultValue:"striped centered"
    },
    LiveEdit:{
        type: Module.Types.Boolean,
        defaultValue:false
    },
    FilterInput: {
        type: Module.Types.Array,
        arrType: Module.Types.Object
    }
}

ListModule.Outputs = {
    onFilters: {}
}

ListModule.Category = "Nikatlas";
ListModule.EditPosition = "top-right";
export default ListModule;