/**
 * Generic List accepts an array of fields to update any resource
 */

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

import { Link } from 'react-router-dom';

import { Typography, Button, Table, Modal, Space, Switch, Popconfirm, message, Skeleton } from 'antd';

import { withRouter } from 'react-router-dom';

import './menu-list.scss';

import { ReloadOutlined, OrderedListOutlined, PicCenterOutlined, DeleteOutlined } from '@ant-design/icons';

// import TableSettings from './../../' './table-settings/table-settings';

import { Location } from './../../../../utils/location/location.utils'

import { ModelColumns, UserPreferences } from './../../../../models/';

import moment from 'moment';

const { Title } = Typography;

/**
 * Generic List
 *
 * @param {*} param0
 */
function MenuList({
    menu,
    match,
    model = {
        columns: [],
        actions: [],
        queries: [],
        filterDate: () => { },
    },
    actions = [],
    queries = model.queries,
    disableAdd = model.disableAdd,
    disableEdit = model.disableEdit,
    disableDelete = model.disableDelete,
    disableAddModal = model.disableAddModal,
    additional_queries = [],

    config = {}
    // columns = schema.columns || [],
    // isDirect = schema.isDirect,
    // disableUpload = schema.disableUpload,
    // disableAdd = schema.disableAdd,
    // disableSelect = schema.disableSelect,
    // queries = schema.queries || [],
    // actions = schema.actions || [],
}) {
    // console.log(model);

    const step = Location.search().step || 1;

    const [today, setToday] = useState(moment());

    const [records, setRecords] = useState({ [model.name]: [] });

    const [single, setSingle] = useState({});

    const [columns, setColumns] = useState([]);

    const { params } = match;

    const [loading, setLoading] = useState(true);

    let cardView = JSON.parse(localStorage.getItem('card-view'))

    const [view, setView] = useState(cardView);

    const [selected, setSelected] = useState([]);

    const [visible, setVisible] = useState(false);

    const [layout, setLayout] = useState({});

    // Index for the columns : #Note This should be moved to a generic utils to make this complete leaner
    let columnIndex = [
        {
            title: '#',
            dataIndex: 'index',
            render: (value, item, index) => (options.page - 1) * options.pageSize + index + 1,
        },
    ]

    let nextStep = parseInt(step) + 1;

    // Actions for the generic list
    let columnActions = [

        {
            title: '',
            key: '',
            render: (text, record) => {
                return (
                    <Space size="middle">

                        {/* Edit */}
                        {disableAddModal() || !model.ModalAddComponent ? null : (
                            <Button type="dashed" onClick={() => {

                                setSingle({ ...record });

                                setVisible(true);
                            }}>
                                Edit
                            </Button>
                        )}
                        {/* Edit Ends */}

                        {/* Edit */}
                        {disableDelete() ? null : (
                            <Popconfirm
                                title="Are you sure you want to delete this record ? "
                                onConfirm={() => deleteRecord(record)}
                                onCancel={() => { }}
                                okText="Yes"
                                cancelText="No"
                            >
                                <Button size="small">
                                    <DeleteOutlined />
                                </Button>
                            </Popconfirm>
                        )}
                        {/* Edit Ends */}


                    </Space>
                );
            },
        },



        {
            title: '',
            key: 'action',
            render: (text, record) => {
                return (
                    <Space size="middle">
                        {!model.hideView && !actions.length ? <Link to={`/${model.name}/${text.id}?step=${nextStep}`}>View</Link> : null}

                        {actions.map((action) => (
                            <Link to={action.url(record)}>{action.caption}</Link>
                        ))}
                    </Space>
                );
            },
        },
    ]

    const cols = [
        ...columnIndex
        ,
        ...model.columns.map((entry) => {
            if (entry.sort) {
                return {
                    render: (record) => {
                        if (entry.render) {
                            return entry.render(record);
                        } else {
                            return entry.field.split('.').reduce((acc, part) => acc && acc[part], record);
                        }
                    },
                    title: entry.caption,
                    key: entry.field,
                    sorter: (a, b) => entry.sort(a, b),
                    sortDirections: ['ascend', 'descend', 'ascend'],
                };
            } else {
                return {
                    render: (record) => {
                        if (entry.render) {
                            return entry.render(record);
                            // return entry.field.split('.').reduce((acc, part) => acc && acc[part], record);
                        } else {
                            return entry.field.split('.').reduce((acc, part) => acc && acc[part], record);
                        }
                        // return record[entry.field]
                    },
                    title: entry.caption,
                    key: entry.field,
                };
            }
        }),
        ...columnActions,
    ];

    const [options, setOptions] = useState({
        page: 1,
        current: 1,
        pageSize: 20,
    });

    useEffect(() => {

        loadListing();

    }, []);



    function loadListing() {

        if (menu && menu.model && menu.model.id) {
            // loadConfiguration(menu.model.id);

            loadConfiguration(menu.id).then(() => {

                loadData(queries);

            });

        } else {
            setColumns(cols);

            loadData(queries);

        }

    }


    /**
     * Load the configuration
     */
    function loadConfiguration(id) {

        var queries = [{
            field: 'menu_id',
            value: id
        }]

        return UserPreferences.get(queries).then((result) => {

            // console.log(result);

            if (result.user_preferences.length) {

                let cols = result.user_preferences[0].selected;

                setLayout(result.user_preferences[0]);

                let mapped = cols.map((record) => {

                    return {
                        dataIndex: record.field,
                        title: record.caption,
                        key: record.field
                    }
                })

                setColumns(

                    [
                        ...columnIndex
                        ,

                        ...mapped,
                        ...columnActions,

                    ]
                )

            } else {


            }
        })
    }

    function changeView(result) {
        setView(result);

        localStorage.setItem('card-view', result);
    }

    /**
     *
     */
    const getRecords = (today) => {
        // console.log(model);

        let firstStepQueries = [{
            field: 'step',
            value: parseInt(step) || 1
        }]

        var queries = [

            ...additional_queries,

            ...firstStepQueries,
        ];

        if (!additional_queries.length) {

            queries.push({
                field: 'header_id',
                value: null
            })
        }

        // if (model.filterDate()) {
        //     queries.push({
        //         field: 'created_date',
        //         value: moment(today).startOf('day').valueOf(),
        //     });
        // }

        return model.get(queries, config).then((result) => {
            console.log(result);

            setRecords(result);

            setLoading(false);
        });
    };

    const loadData = (today, queries) => {
        // console.log('queries', queries);

        setLoading(true);

        setToday(today);

        setSelected([]);

        getRecords(today, queries);
    };

    function refresh() {
        loadData(today, queries);
    }

    /**
     * Delete multiple selected records
     */
    function deleteSelected() {

        setLoading(true);

        Promise.all(
            selected.map((entry) => model.delete(entry.id, { hideAlert: true }))
        ).then(() => {

            message.success('Selected records has been deleted');

            setLoading(false);

            setSelected([]);

            loadData();
        });
    }

    /**
     * Delete the record
     */
    function deleteRecord(record) {

        return model.delete(record.id).then(() => {

            loadData();

        })
    }

    /**
     * Close the modal
     */
    function closeModal(refresh) {

        setSingle({});

        setVisible(false);

        if (refresh) {
            loadData();
        }
    }

    // rowSelection object indicates the need for row selection
    const rowSelection = {
        onChange: (selectedRowKeys, selectedRows) => {
            console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);

            setSelected(selectedRows);
        },
        getCheckboxProps: (record) => ({
            disabled: record.name === 'Disabled User', // Column configuration not to be checked
            name: record.name,
        }),
    };

    return (
        <section className="generic-list">
            {/* Table Header */}
            <div className="table-header">
                <div className="table-title">
                    <Title level={4}>{model.name}</Title>

                    <p>{loading ? 'Loading records' : `${records[model.name].length} records`}</p>
                </div>

                {/* Table Filters */}
                <div className="table-filters">
                    <Space direction="vertical" size={12}>
                        {/* <RangePicker onChange={updateFilter} /> */}
                    </Space>
                </div>
                {/* Table Filters Ends */}

                <div className="table-actions">
                    <div className="button-container">

                        {/* Selected Actions */}
                        {selected.length ? (
                            <>
                                {selected.length} selected .
                                <Popconfirm
                                    title="Are you sure you want to delete the selected rows ? "
                                    onConfirm={() => deleteSelected()}
                                    onCancel={() => { }}
                                    okText="Yes"
                                    cancelText="No"
                                >
                                    <Button size="small">
                                        <DeleteOutlined />
                                    </Button>
                                </Popconfirm>

                                {/* Custom Actions */}
                                {
                                    actions.map((action) => {
                                        return (
                                            <Popconfirm
                                                title="Are you sure you want to perform the action on selected rows ? "
                                                onConfirm={() => action.onClick(selected, refresh)}
                                                onCancel={() => { }}
                                                okText="Yes"
                                                cancelText="No"
                                            >
                                                <Button size="small">{action.caption}</Button>
                                            </Popconfirm>
                                        );
                                    })
                                }
                                {/* Custom Actions */}

                            </>
                        ) : null}

                        <Space size="small">
                            {/* {model.filterDate() ? (
                                 <DatePicker defaultValue={today} format={'DD/MM/YYYY'} allowClear={false} onChange={loadData} />
                             ) : null} */}

                            <Switch
                                size={'small'}
                                defaultChecked
                                onChange={changeView}
                                checked={view}
                                checkedChildren={<OrderedListOutlined />}
                                unCheckedChildren={<PicCenterOutlined />}
                            />

                            <Button onClick={refresh} type="secondary" size={'small'}>
                                <ReloadOutlined />
                            </Button>


                            {/* <Button onClick={refresh} type="secondary" size={'small'}>
                                 <TableOutlined />
                             </Button> */}

                            {/*  */}
                            {/* {!loading ? <TableSettings refresh={loadListing} layout={layout} menu={menu} model={model} onUpdate={() => { }} /> : null} */}


                            {/* <Button onClick={exportTableLocal} type="secondary" size={'small'}>
                                 Download
                             </Button> */}

                            {/*table data export to csc component*/}
                            {/* {records && <ExportReactCSV csvData={expRecord} />} */}

                            {/* <Button disabled={options.page <= 1} size="small" onClick={() => { }}>
                                 <CaretLeftOutlined />
                             </Button>
 
                             <Button size="small" onClick={() => { }}>
 
                                 <CaretRightOutlined />
 
                             </Button> */}

                            {/* {
                                 disableUpload
                                     ?
                                     null
                                     :
                                     <Button type="dashed">
                                         <Link to={`/${city}/${model}/upload/file`}>
                                             Upload
                                         </Link>
                                     </Button>
                             } */}

                            {/* Add Redirection */}
                            {/* {disableAdd ? null : (
                                 <Button type="dashed" size={'small'}>
                                     <Link to={`/${model.name}/create`}>Add</Link>
                                 </Button>
                             )} */}
                            {/* Add Redirection Ends */}

                            {disableAddModal() || !model.ModalAddComponent ? null : (
                                <Button size={'small'} type="dashed" onClick={() => setVisible(true)}>
                                    Add
                                </Button>
                            )}
                        </Space>
                    </div>
                </div>
            </div>

            {/* Table Header Ends */}

            {loading ? (
                <Skeleton type="listing" />
            ) : (
                <>
                    <>
                        {!view ? (
                            <Table
                                // ref={(ref) => { tableRef = ref }}
                                className="table-exportable"
                                loading={loading}
                                size="small"
                                rowSelection={rowSelection}
                                scroll={{ x: true, y: 750 }}

                                // scroll={{ x: true, y: 750 }}
                                rowKey={(record) => record.id}
                                // rowKey={record => record[model + 'Id']}
                                dataSource={records[model.name]}
                                columns={columns}
                                // onChange={handleTableChange}
                                pagination={false}
                            ></Table>
                        ) : (
                            <CardList model={model} data={records[model.name]} />
                        )}
                    </>
                </>
            )}

            {/* Add Modal */}
            <Modal destroyOnClose confirmLoading={loading} title="Add New" visible={visible} onCancel={() => { closeModal() }} footer={null}>
                <model.ModalAddComponent
                    match={match}
                    menu={menu}
                    model={model}
                    additional_queries={additional_queries}
                    formContent={single}

                    callback={() => {
                        closeModal(true);
                    }}
                />
                {/* <FormCreator formContent={{ [model]: {} }} modelIndex="requestId" model={model} onSubmit={createRecord} config={step} /> */}
            </Modal>

            {/* Add Modal Ends */}
        </section>
    );
}

export default withRouter(MenuList);

function CardList({ model, data, ...props }) {
    return data.map((record, index) => {
        return <model.Card index={index} key={index} record={record} {...record} {...props} />;
    });
}
