/**
 * 
 * A Single Dashboard that should be able to manage any process in a business
 * according to configred by system . 
 * 
 * A process of different steps , each step linked to different roles of users and has a form/page to complete
 * that particular step is part of this module . 
 * 
 * 
 * 
 * @description Component for updating each process 
 * @author Ashique
 * 
 */


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

import { Timeline, Card, Skeleton, Button, Modal, Typography, Form, Select, message, Tag } from 'antd';

import { Process, ProcessTransactions, Steps } from '../../../';

import TaskForm from './../task-form/task-form';

import './process-dashboard.scss';

import TaskStatus from './../task-status/task-status';

import DateUtils from '../../../../utils/date/date.utils';

import { ClockCircleOutlined, CopyOutlined, CheckCircleOutlined, LoadingOutlined, EditOutlined, ReloadOutlined } from '@ant-design/icons';

import { CopyToClipBoard } from '../../../..';

import { GlobalContext } from './../../../../Store';

const { Title } = Typography;

const { Option } = Select;

let stepMaster = {
    ongoing: {
        icon: LoadingOutlined,
        color: 'blue'
    },
    pending: {
        icon: ClockCircleOutlined,
        color: 'orange'
    },
    completed: {
        icon: CheckCircleOutlined,
        color: 'green'
    },

    waiting: {
        icon: ClockCircleOutlined,
        color: 'red'
    },

}

/**
 * 
 */
export default function ProcessDashboard({ id, identifier, callback = () => { } }) {

    const { user = { locations: [] } } = useContext(GlobalContext);

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

    const [process, setProcess] = useState([]);

    const [transactionmodal, setTransactionmodal] = useState(false);

    useEffect(() => {

        // We have to load the process for the identified received as a property

        // The process / steps are recorded specific to a an id which can be of any model . 
        getProcess();

        return () => {

        }

    }, [])

    /**
     * Get the process of an identifier 
     * 
     * @returns 
     */
    function getProcess() {

        setLoading(true);

        var queries = [{
            field: 'modelIdentifier',
            value: identifier
        }]

        // Get the process with the current status of an id passed . 
        return Process.getProcessTimeline({ identifier, id }).then((result) => {

            setProcess(result);

            console.log(result);

            setLoading(false);

        });
    }


    /**
     * Revert the modal
     */
    function openRevertModal() {

        setTransactionmodal(true);
    }


    /**
     * Close the revert modal 
     */
    function closeRevertModal() {
        setTransactionmodal(false);

    }

    return (<div className="process-dashboard card">

        {/* 
        <div className="page-header">

            <Title level={5}>
                Process Dashboard
            </Title>

            <div className="actions">

                {
                    user.isAdmin
                    &&
                    <Button size={'small'} onClick={() => { openRevertModal() }}>
                        <ReloadOutlined />
                        Revert
                    </Button>
                }

            </div>
        </div> */}

        {
            loading
                ?
                <>

                    <strong className="process-title">
                        Loading content ,
                    </strong>

                    <Skeleton />
                </>

                :
                <>

                    {
                        process.map((records) => {

                            // If there is a process transaction record this process has started 
                            let { process_transactions = [] } = records;

                            return (<>

                                <div className='page-header'>
                                    <div>

                                        <strong className="process-title">
                                            {records.name}
                                        </strong>

                                        <p className="process-description">
                                            <small>
                                                {records.description}
                                            </small>
                                        </p>
                                    </div>

                                    <div className='actions'>

                                        <CopyToClipBoard id={records.id} record={records} />


                                        {
                                            user.isAdmin
                                            &&
                                            <Button size={'small'} onClick={() => { openRevertModal() }}>
                                                <ReloadOutlined />
                                                Revert
                                            </Button>
                                        }

                                    </div>

                                </div>

                                {
                                    process_transactions.length
                                        ?
                                        <small className='timeline'>
                                            {/* {DateUtils.displayFirestoreTime(process_transactions[0].start_time)} -  {process_transactions[0].completed ? DateUtils.displayFirestoreTime(process_transactions[0].end_time) : 'Pending'} */}
                                        </small>
                                        :
                                        null
                                }

                                <Timeline className="process-timeline">

                                    {/* Steps List */}
                                    <StepsList id={id} steps={records.steps} callback={getProcess} />
                                    {/* Steps List Ends */}

                                </Timeline>
                            </>)
                        })
                    }

                    {/* Add Modal */}
                    <Modal destroyOnClose confirmLoading={loading} title="Revert" visible={transactionmodal} onCancel={() => { closeRevertModal() }} footer={null}>

                        <RevertProcessTransaction id={id} process={process} callback={() => {

                            closeRevertModal()
                        }} />

                    </Modal>
                    {/* Add Modal Ends */}

                </>
        }

    </div >)

}

/**
 * The Timeline item that displays a step
 */
function StepTimelineItem({ id, color, Icon, step, step_transactions, callback }) {

    const [body, setBody] = useState({});

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

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

    const { user = { locations: [] } } = useContext(GlobalContext);

    /**
  * Function to open editModal for Step
  * 
  * @param {*} step 
  */
    function openEditModal(step) {

        setVisible(true);

        setBody(step)

    }

    /**
     * 
     * @param {*} step 
     */
    async function startStep(step) {

        // Batch 
        let app = Process.getFireStoreApp();

        // Starting a batched write
        let batch = app.batch();

        let body = {
            record_id: id,
            model_identifer: 'Candidates'
        }

        await Process.startStepBatch({ batch, step, body });

        await batch.commit();

        message.success("Step Started");
    }

    /**
     * 
     * @param {*} step 
     */
    async function completeStep(step) {

        // Batch 
        let app = Process.getFireStoreApp();

        // Starting a batched write
        let batch = app.batch();

        let body = {
            record_id: id,
            model_identifer: 'Candidates'
        }

        await Process.stopStepBatch({ batch, step, body });

        message.success("Step Ended");

    }

    /**
     * 
     * @param {*} step 
     */
    function closeModal() {

        setVisible(false);
    }


    return (<Timeline.Item color={color} dot={<Icon />} >

        {/* Timeline Step Template */}
        <div className="timeline-content">

            <p className={'timeline-title'}>
                {step.name}

                <p className={'timeline-description'}>
                    <small>
                        {step.description}
                    </small>
                </p>
            </p>

            {/* Actions for a step */}
            <div className="actions">

                {user.isAdmin && <>

                    <CopyToClipBoard record={step} id={step.id} />

                    <Button size={'small'} onClick={() => { openEditModal(step) }}>

                        <EditOutlined />

                        Edit

                    </Button>

                    <Button size={'small'} onClick={() => { startStep(step) }}>

                        Start

                    </Button>

                    <Button size={'small'} onClick={() => { completeStep(step) }}>

                        Complete

                    </Button>

                </>}

            </div>
            {/* Actions for a step Ends */}

        </div>
        {/* Timeline Step Template Ends */}

        {/* Summary of Step Activity */}
        <TaskStatus id={id} color={color} step={step} step_transactions={step_transactions} />
        {/* Summary of Step Activity Ends */}

        {/* Form for the Step */}
        {step.formEnabled && <Card className="task-form-card">

            <h1>
                Form Enabled Value {step.formEnabled} - {step.name}

            </h1>

            <TaskForm
                record_id={id}
                step={step}

                callback={callback}

            />

        </Card>}
        {/* Form for the Step Ends */}


        {
            step.sub_steps.length ?
                <>
                    <Timeline className="process-timeline">

                        <StepsList id={id} steps={step.sub_steps} />

                    </Timeline>
                </>
                :
                null
        }


        {/* Add Modal */}
        <Modal destroyOnClose confirmLoading={loading} title="Edit Step" visible={visible} onCancel={() => { closeModal() }} footer={null}>
            <Steps.ModalAddComponent
                // match={match}
                model={Steps}
                additional_queries={[]}
                formContent={body}

                callback={() => {
                    closeModal(true);
                }}
            />
        </Modal>
        {/* Add Modal Ends */}

        {/* </>
        } */}

    </Timeline.Item>)

}


/**
 * List of Steps inside a Timline
 */
function StepsList({ id, steps = [], callback }) {

    return (<>

        {
            steps.map((step) => {

                let color = stepMaster[step.current_state].color;

                let Icon = stepMaster[step.current_state].icon;

                let step_transactions = false;

                if (step.step_transactions && step.step_transactions.length) {

                    step_transactions = step.step_transactions[0];

                }

                return (<>

                    {/* Details of the step */}
                    <StepTimelineItem
                        id={id}
                        color={color}
                        Icon={Icon}
                        step={step}
                        step_transactions={step_transactions}

                        callback={callback}
                    />
                    {/* Details of the step Ends */}


                    {/* Form for the Step */}
                    {/* {step.formEnabled && <Card className="task-form-card">

                        <h1>
                            Form Enabled Value {step.formEnabled} - {step.name}

                        </h1>

                        <TaskForm
                            record_id={id}
                            step={step}

                        // callback={callback}

                        />

                    </Card>} */}
                    {/* Form for the Step Ends */}

                </>)
            })
        }

    </>)

}




/**
 * 
 * 
 * @returns 
 */
function RevertProcessTransaction({ id, process = [], callback }) {

    // const form = useRef(null)

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

    const [processtransactions, setProcesstransactions] = useState([])

    useEffect(() => {

        getProcessTransaction();

        return () => {
        }
    }, [])

    /**
     * 
     * @returns 
     */
    function getProcessTransaction() {

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

        return ProcessTransactions.get(queries).then(({ process_transactions }) => {

            setProcesstransactions(process_transactions);

            console.log(process_transactions);

        })
    }

    /**
     * On Submit of form , Change the process transaction to specific step
     */
    function onSubmit(values) {

        // Batch 
        let app = Process.getFireStoreApp();

        // Starting a batched write
        let batch = app.batch();

        setLoading(true);

        console.log(values);

        Process.triggerProcessBatch(batch, values.process_id, {}, processtransactions[0].id).then(() => {

            message.success("Reverted case to ", values.process_id);

            setLoading(false);

            callback();

        })
    }

    return (<>

        <Title level={4}>
            Revert Step
        </Title>

        <Form
            // form={form}
            layout="vertical"
            onFinish={onSubmit}>

            <Form.Item label="Process" name="process_id" required>
                <Select style={{ width: '100%' }}>

                    {process.map((staff) => <Option value={staff.id}>{staff.name}</Option>)}

                </Select>
            </Form.Item>

            <Form.Item >
                <Button loading={loading} type="primary" htmlType="submit">
                    Submit
                </Button>
            </Form.Item>

        </Form>
    </>)

}