import { Button, Input, Layout, Steps, Transfer, Typography, message, notification } from 'antd';
import React, { useEffect, useState, useRef } from 'react';
import { selectorService } from '../../services/selectorService';
import { CheckSquareOutlined, CloseSquareOutlined, FormOutlined, LoadingOutlined } from '@ant-design/icons';
import { useLocation, useHistory } from 'react-router-dom';
import './CreateBatch.css';

const steps = [
    {
        title: 'Step 1',
        description: "Write a Batch Name",
        //   content: <CreateExamName selectorState={state} parentCallback={callbackFunctionStep1} />,
    },
    {
        title: 'Step 2',
        description: "Add Students",
        //   content: <SelectSubjects selectorState={state} parentCallback={(childData) => { callbackFunctionStep2(childData) }} />,
    }
];

const CreateBatchNew = () => {
    const loc = useLocation();
    const history = useHistory();
    const mounted = useRef(true);
    const [currentStep, setCurrentStep] = useState(0);
    const [batchName, setBatchName] = useState("");
    const [pageState, setPageState] = useState({
        sourcePoolLoading: false,
        batchPoolLoading: false,
        buttonLoading: false,
        inputEditActive: false,
        temporaryName: ""
    });
    const [batchID, setBatchID] = useState("");

    // for step - 2
    const [dataSource, setDataSource] = useState([]);
    const [targetKeys, setTargetKeys] = useState([]);
    const [selectedKeys, setSelectedKeys] = useState([]);

    useEffect(() => {
        mounted.current = true;
        if(loc && loc.state && loc.state.id) {
            setBatchID(loc.state.id);
            setBatchName(loc.state.name);
            setPageState(prev => ({...prev, temporaryName: loc.state.name}));
            setCurrentStep(1);
        }
        if (currentStep === 1) {
            getAllStudents();
            getStudentsFromBatch();
        }
        return () => {
            mounted.current = false;
        }
    }, [currentStep]);

    async function getAllStudents(page_size = 20, page_number = 1) {
        setPageState(prev => ({
            ...prev, sourcePoolLoading: true
        }));
        try {
            const res = await selectorService.getAllUser(page_size, page_number);
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (!Array.isArray(res.result.users) || (Array.isArray(res.result.users) && res.result.users.length === 0)) {
                mounted.current && setPageState(prev => ({...prev, batchPoolLoading: false}));
                return;
            }
            let skipCounter = false;
            if(res.result && res.result.total_count && res.result.total_count > page_size) {
                skipCounter = true;
                getAllStudents(res.result.total_count, 1);
                return;
            }
            const users = res.result.users.filter((x) => x.role === "Student").map(user => {
                // key: i.toString(),
                // title: `content${i + 1}`,
                // description: `description of content${i + 1}`,
                if(user.first_name && user.last_name) {
                    return {
                        key: user.id+"",
                        title: `${user.first_name} ${user.last_name}`,
                        id: user.id,
                    }
                } else {
                    return {
                        key: user.id+"",
                        title: `${user.email_id}`,
                        id: user.id,
                    }
                }
            });
            // console.log(users);
            mounted.current && setDataSource([...users]);
            mounted.current && setPageState(prev => ({...prev, sourcePoolLoading: false}));
        } catch (error) {
            console.log(error);
            mounted.current && message.error(error);
            mounted.current && setPageState(prev => ({...prev, sourcePoolLoading: false}));
        }
    }

    async function getStudentsFromBatch() {
        setPageState(prev => ({
            ...prev, batchPoolLoading: true
        }));
        try {
            const res = await selectorService.getStudentsOfBatch(batchID);
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (!Array.isArray(res.result) || (Array.isArray(res.result) && res.result.length === 0)) {
                mounted.current && setPageState(prev => ({...prev, batchPoolLoading: false}));
                return;
            }
            const usersInBatch = []
            for(let i of res.result) {
                // console.log(i.id);
                usersInBatch.push(`${i.id}`);
            }
            // console.log(usersInBatch);
            mounted.current && setTargetKeys([...usersInBatch]);
            mounted.current && setPageState(prev => ({...prev, batchPoolLoading: false}));
        } catch (error) {
            console.log(error);
            mounted.current && message.error(error);
            mounted.current && setPageState(prev => ({...prev, batchPoolLoading: false}));
        }
    }

    function handleBatchNameInput(event, type) {
        // console.log(event.target.value);
        const { value } = event.target;
        if (!type) setBatchName(value);
        if (type === "temp") {
            setPageState(prev => ({ ...prev, temporaryName: value }));
        }
    }
    async function createNewBatch() {
        setPageState(prev => ({
            ...prev, buttonLoading: true
        }));
        if (!batchName) {
            message.error("Please enter a Batch name before pressing on Create");
            return;
        }
        message.loading("Creating the Batch, give us a few second...");
        try {
            const res = await selectorService.createBatch({
                name: batchName, description: "",
                photo: ""
            });
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (mounted.current) {
                setPageState(prev => ({
                    ...prev, buttonLoading: false, temporaryName: batchName
                }));
                setBatchID(res.result.id);
                setCurrentStep(currentStep + 1);
            }
        } catch (error) {
            process.env.NODE_ENV === "development" && console.log(error);
            if(mounted.current) {
                notification.error({
                    message: "Something went wrong, please try again"
                });
                setPageState(prev => ({
                    ...prev, buttonLoading: false
                }));
            }
        }
    }

    function handleCancelForInput() {
        setPageState(prev => ({
            ...prev,
            inputEditActive: false,
            temporaryName: batchName
        }));
    }

    async function handleUpdateForInput() {
        if(pageState.temporaryName === batchName) {
            setPageState(prev => ({ ...prev, inputEditActive: false }));
            return;       
        }
        setPageState(prev => ({ ...prev, buttonLoading: true }));
        message.loading("Changing Batch Name...");
        try {
            const res = await selectorService.updateBatchName({
                id: batchID, name: pageState.temporaryName,
                description: "", photo: ""
            });
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (+res.status.code > 0 && mounted.current) {
                setBatchName(pageState.temporaryName);
                setPageState(prev => ({ ...prev, buttonLoading: false, inputEditActive: false }));
                message.success("Operation Success! Batch name has been changed");
            }
        } catch (error) {
            process.env.NODE_ENV === "development" && console.log(error);
            if(mounted.current) {
                notification.error({ message: "Something went wrong while updating the name, operation failed" });
                setPageState(prev => ({ ...prev, buttonLoading: false }));
            }
        }
    }

    async function handleUserAddition() {
        setPageState(prev => ({ ...prev, buttonLoading: true }));
        message.loading("Adding Users to Batch...");
        try {
            const convertedTargetKeys = targetKeys.map(key => (Number(key)));
            const res = await selectorService.addToBatch({idList: convertedTargetKeys, batch_id: batchID});
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if(mounted.current) {
                message.success("Operation Success! Students have been added!");
                setTimeout(() => history.push("/viewbatch"), 700);
            }
        } catch (error) {
            process.env.NODE_ENV === "development" && console.log(error);
            if(mounted.current) {
                notification.error({ message: "Something went wrong while updating the name, operation failed" });
                // setPageState(prev => ({ ...prev, buttonLoading: false }));
            }
        }
    }

    const onChange = async (nextTargetKeys, direction, moveKeys) => {
        // console.log('targetKeys:', nextTargetKeys);
        // console.log('direction:', direction);
        // console.log('moveKeys:', moveKeys);
        try {
            if(direction === "left") {
                message.loading("Removing Users from Batch...");
                const convertedMoveKeys = moveKeys.map(key => (Number(key)));
                const res = await selectorService.deleteFromBatch({idList: convertedMoveKeys, batch_id: batchID})
                if (+res.status.code < 0) {
                    throw res.status.message[0];
                }
                if(mounted.current) {
                    message.success("Operation Success! Students have been added!");
                    setTargetKeys(nextTargetKeys);
                }
            } else {
                setTargetKeys(nextTargetKeys);
            }
        } catch (error) {
            console.log(error);
            message.error("Failed to remove user from the Batch");
        }
    };

    const onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
        // console.log('sourceSelectedKeys:', sourceSelectedKeys);
        // console.log('targetSelectedKeys:', targetSelectedKeys);
        setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
    };

    return (
        <Layout.Content
            className="site-layout-background batch-creation" style={{ padding: 24, margin: 0 }}>
            {/* <Layout className='createExamLayoutHeader'>Create Exam</Layout> */}
            {/* <Layout className='createExamLayout'> */}
                <Steps current={currentStep}>
                    {steps.map(item => (
                        <Steps.Step key={item.title} title={item.title} description={item.description} />
                    ))}
                </Steps>

                {currentStep === 0 && <div className="step-1">
                    <Typography.Text strong style={{ color: "var(--font-color-primary)" }}>
                        Batch Name
                    </Typography.Text>
                    <Input placeholder='Enter Batch Name here' onChange={handleBatchNameInput} value={batchName} />
                </div>}
                {currentStep === 0 && <div data-need-margin={"false"} className="button-container">
                    <Button type="primary" loading={pageState.buttonLoading} onClick={createNewBatch}>
                        Create Batch
                    </Button>
                </div>}


                {currentStep === 1 && <div className='step-2'>
                    <div className='title-section'>
                        <Typography.Text strong style={{ color: "var(--font-color-primary)" }}>
                            Batch Name
                        </Typography.Text>
                        {pageState.inputEditActive && <Input placeholder='Enter Batch Name here' onChange={(e) => handleBatchNameInput(e, "temp")} value={pageState.temporaryName} />}
                        {pageState.inputEditActive && <div className={"vertical-stacked-button"}>
                            <div onClick={handleCancelForInput}><CloseSquareOutlined style={{ fontSize: 14, color: 'red' }} /></div>
                            <div onClick={handleUpdateForInput}><CheckSquareOutlined style={{ fontSize: 14, color: 'var(--font-color-primary)' }} /></div>
                        </div>}
                        {!pageState.inputEditActive && <Typography.Text>{batchName}</Typography.Text>}
                        {!pageState.inputEditActive &&
                            <Button onClick={() => setPageState(prev => ({ ...prev, inputEditActive: true }))}
                                icon={<FormOutlined />} />
                        }
                    </div>
                    <div className='student-selector'>
                        {pageState.sourcePoolLoading || pageState.batchPoolLoading
                        ? <div className='center-flex'><Typography.Text><LoadingOutlined spin/> Loading resource...</Typography.Text></div>
                        : <Transfer
                            dataSource={dataSource}
                            titles={['Students', 'Students of Batch']}
                            targetKeys={targetKeys}
                            selectedKeys={selectedKeys}
                            onChange={onChange}
                            onSelectChange={onSelectChange}
                            pagination={{
                                pageSize: 20,
                            }}
                            // onScroll={onScroll}
                            render={(item) => item.title}
                        />}
                    </div>
                </div>}
                <div className="steps-action">
                    {currentStep < steps.length - 1}
                    {currentStep === steps.length - 1 && (
                        <div data-need-margin={"false"} className="button-container">
                            <Button type="primary" loading={pageState.buttonLoading} onClick={handleUserAddition}>
                                Add Users to Batch
                            </Button>
                        </div>
                    )}
                </div>
            {/* </Layout> */}
        </Layout.Content>
    );
}

export default CreateBatchNew;
