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

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

const CreateClass = () => {
    const loc = useLocation();
    const history = useHistory();
    const mounted = useRef(true);
    const [currentStep, setCurrentStep] = useState(0);
    const [classLabel, setClassLabel] = useState("");
    const [pageState, setPageState] = useState({
        sourceLoading: false,
        buttonLoading: false,
        inputEditActive: false,
        temporaryName: "",
        structureTemp: "",
        activeEditIndex: "",
    });
    const [classID, setClassID] = useState("");

    // step-2 state variables
    const [subStructure, setSubStructure] = useState([
        {
            name: "",
            id: -1,
            topics: [{
                name: "",
                id: -1
            }]
        }
    ]);
    let subjectCount = subStructure.length;

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

    async function fetchClassDetail() {
        try {
            const res = await selectorService.getClassDetails(classID);
            if(+res.status.code < 0) {
                throw res.status.message[0];
            }
            if(mounted.current) {
                process.env.NODE_ENV === "development" && console.log(res);
                setSubStructure([...res.result.subjects]);
                setPageState(prev => ({...prev, sourceLoading: false, buttonLoading: false, activeEditIndex: res.result.subjects.length-1}));
            }
        } catch (error) {
            console.log(error);
            message.error("Something went wrong, please try again");
        }
    }

    function handleClassNameInput(event, type) {
        // console.log(event.target.value);
        const { value } = event.target;
        if (!type) setClassLabel(value);
        if (type === "temp") {
            setPageState(prev => ({ ...prev, temporaryName: value }));
        }
    }

    async function creationOfClass() {
        setPageState(prev => ({
            ...prev, buttonLoading: true
        }));
        if (!classLabel) {
            message.error("Please enter a Class name before pressing on Create");
            return;
        }
        message.loading("Creating the Class, give us a few second...");
        try {
            const res = await selectorService.createClass({ name: classLabel });
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (mounted.current) {
                setClassID(res.result.id);
                setPageState(prev => ({ ...prev, temporaryName: classLabel }));
                setCurrentStep(currentStep + 1);
            }
        } catch (err) {
            process.env.NODE_ENV === "development" && console.log(err);
            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: classLabel
        }));
    }

    async function handleUpdateForInput() {
        if(pageState.temporaryName === classLabel) {
            setPageState(prev => ({ ...prev, inputEditActive: false }));
            return;       
        }
        setPageState(prev => ({ ...prev, buttonLoading: true }));
        message.loading("Updating Class Name...");
        try {
            const res = await selectorService.updateClass({
                id: classID, name: pageState.temporaryName,
            });
            if (+res.status.code < 0) {
                throw res.status.message[0];
            }
            if (+res.status.code > 0 && mounted.current) {
                setClassLabel(pageState.temporaryName);
                setPageState(prev => ({ ...prev, buttonLoading: false, inputEditActive: false }));
                message.success("Operation Success! Class 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 }));
            }
        }
    }

    function handleInputOperation(e, location) {
        // const type = location.split("-")[0];
        // const index = location.split("-")[1];
        const {value} = e.target;
        // console.log(type, index, value);
        setPageState(prev => ({...prev, structureTemp: value}));

    }

    async function submitSyllabusStructure() {
        const index = pageState.activeEditIndex;
        setPageState(prev => ({...prev, buttonLoading: true}));
        try {
            if(subStructure[index].id < 0) {
                console.log("here to subject")
                const res = await selectorService.addSubjectToClass({name: pageState.structureTemp, id: classID});
                if(+res.status.code < 0) {
                    throw res.status.message[0];
                }
                if(mounted.current) {
                    const subjectArray = subStructure;
                    subjectArray[index] = {
                        ...subjectArray[index],
                        name: res.result.name,
                        id: res.result.id
                    }
                    setPageState((prev) => ({...prev, buttonLoading: false, structureTemp: ""}));
                    setSubStructure(() => ([...subjectArray]));
                    fetchClassDetail();
                }
            } else {
                console.log("here to topic")
                const res = await selectorService.addTopicToClass({name: pageState.structureTemp, id: subStructure[index].id});
                if(+res.status.code < 0) {
                    throw res.status.message[0];
                }
                console.log(res.result);
                if(mounted.current) {
                    const subjectArray = subStructure;
                    subjectArray[index].topics = [...subjectArray[index].topics, {id: res.result.id, name: res.result.name}]
                    setPageState((prev) => ({...prev, buttonLoading: false, structureTemp: ""}));
                    setSubStructure(() => ([...subjectArray]));
                    // fetchClassDetail();
                }
            }
        } catch (error) {
            console.log(error);
            if(mounted.current) {
                message.error("Something went wrong, please try again");
                setPageState((prev) => ({...prev, buttonLoading: false }));
            }
        }
    }

    function pushNewSubjectEntry() {
        let newSubjectInitial = {
            name: "", id: -1, topics: [{name: "", id: -1}]
        };
        if (mounted.current) {
            setSubStructure(prev => ([...prev, newSubjectInitial]));
            // subjectCount has not updated yet, so we don't subtract 1 from it. It updates 
            // after this function is excecuted.
            setPageState(prev => ({...prev, activeEditIndex: subjectCount}));
        }
    }

    async function deleteSubjectRecord(index) {
        setPageState((prev) => ({...prev, buttonLoading: true }));
        try {
            const res = await selectorService.removeSubjectFromClass(index);
            if(+res.status.code < 0) {
                throw res.status.message[0];
            }
            if(mounted.current && +res.status.code === 1) {
                message.success("The subject was removed from the class");
                fetchClassDetail();
            }
        } catch (error) {
            console.log(error);
            if(mounted.current) {
                notification.error({
                    message: "Please make sure no topic under it for the delete operation to be successful"
                });
                setPageState((prev) => ({...prev, buttonLoading: false }));
            }
        }
    }

    async function deleteTopicRecord(index) {
        setPageState((prev) => ({...prev, buttonLoading: true }));
        try {
            const res = await selectorService.removeTopicFromClass(index);
            if(+res.status.code < 0) {
                throw res.status.message[0];
            }
            if(mounted.current && +res.status.code === 1) {
                message.success("The subject was removed from the class");
                fetchClassDetail();
            }
        } catch (error) {
            console.log(error);
            if(mounted.current) {
                notification.error({
                    message: "Please make sure no questions are linked to this topic before deleting the topic"
                });
                setPageState((prev) => ({...prev, buttonLoading: false }));
            }
        }
    }

    return (
        <Layout.Content
            className="site-layout-background class-creation" style={{ padding: 24, margin: 0, overflowY: 'auto' }}>
            {/* <Layout className='createExamLayoutHeader'>Create Exam</Layout> */}
            {/* <Layout className='createExamLayout'> */}
                <Steps key={"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 key={"class-name-1"} strong style={{ color: "var(--font-color-primary)" }}>
                        Class Name
                    </Typography.Text>
                    <Input key={"input-class-1"} placeholder='Enter Class Name here' onChange={handleClassNameInput} value={classLabel} />
                </div>}
                {currentStep === 0 && <div data-need-margin={"false"} className="button-container">
                    <Button key={"btn-create-class"} type="primary" loading={pageState.buttonLoading} onClick={creationOfClass}>
                        Create Class
                    </Button>
                </div>}


                {currentStep === 1 && <div className='step-2'>
                    <div className='title-section'>
                        <Typography.Text key={"class-name-2"} strong style={{ color: "var(--font-color-primary)" }}>
                            Class Name
                        </Typography.Text>
                        {pageState.inputEditActive && <Input key={"input-class-2"} placeholder='Enter Class Name here' onChange={(e) => handleClassNameInput(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 key={"class-label"}>{classLabel}</Typography.Text>}
                        {!pageState.inputEditActive &&
                            <Button key={"edit-btn"} onClick={() => setPageState(prev => ({ ...prev, inputEditActive: true }))}
                                icon={<FormOutlined />} />
                        }
                    </div>
                    {pageState.sourceLoading && <div className='center-flex'><LoadingOutlined spin /></div>}
                    {!pageState.sourceLoading && <div className='add-subject-body'>
                        <Typography.Text type={"secondary"} style={{gridArea: "1/1/1/3", marginBottom: '1rem'}}>
                            <InfoCircleOutlined/> If you are done adding subjects and topic, you can simply navigate out of this page, changes will be saved.
                        </Typography.Text>
                        <Typography.Text key={"add-subject"} strong style={{ color: "var(--font-color-primary)" }}>
                            Add Subjects
                        </Typography.Text>
                        <div className='operations-side'>
                            {subjectCount > 0 &&  subStructure.map((subject, index) => {
                                return <div key={`subject-space-${index}`} className='subject-space'>
                                    {subject?.id > 0 && <div key={`subject-name-${subject.id}`} className='subject-name'>{subject.name}</div>}
                                    {subject.topics.length > 0 && <ul key={`topic-space-${index}`} className='topic-space'>
                                        {subject.topics.map((topic, topicIndex) => {
                                            if(topic.id > 0) {
                                                return <li key={`topic-name-${topic.id}`} 
                                                    className='topic-name'
                                                >
                                                    {topic.name} 
                                                    <Tooltip title={"Delete the Category"}>
                                                        <Button size='small' 
                                                            type={"text"} 
                                                            loading={pageState.buttonLoading} 
                                                            onClick={() => deleteTopicRecord(topicIndex)}
                                                        >
                                                            <DeleteOutlined/>
                                                        </Button>
                                                    </Tooltip>
                                                </li>
                                            }
                                        })}
                                    </ul>}
                                    {pageState.activeEditIndex === index && <div className='input-space'>
                                        {subject.id < 0 && <Input key={"add-subject-name"} name='subject'
                                            placeholder='Write subject name here' 
                                            value={pageState.structureTemp} 
                                            onChange={(e) => handleInputOperation(e, `subject-${index}`)}
                                        />}
                                        {subject.id > 0 && <Input key={"add-topic-name"} name='topic'
                                            placeholder='Write topic name here'
                                            value={pageState.structureTemp} 
                                            onChange={(e) => handleInputOperation(e, `topic-${index}`)}
                                        />}
                                        <Button key={`save-btn-${index}`} onClick={() => submitSyllabusStructure()} loading={pageState.buttonLoading}>Add</Button>
                                        {/* <Button key={`cancel-btn-${index}`} disabled={pageState.buttonLoading}>Cancel</Button> */}
                                    </div>}
                                    {subject.id > 0 && <div className='more-options'>
                                        <Tooltip title={"Add More Topic"}>
                                            <Button type='text' size='small' disabled={pageState.buttonLoading||pageState.activeEditIndex === index}
                                                onClick={() => setPageState(prev => ({...prev, activeEditIndex: index}))}>
                                                <AppstoreAddOutlined />
                                            </Button>
                                        </Tooltip>
                                        <Tooltip title={"Delete the Subject"}>
                                            <Button type='text' size='small' disabled={pageState.buttonLoading}
                                                onClick={() => deleteSubjectRecord(index)}>
                                                    <DeleteOutlined />
                                            </Button>
                                        </Tooltip>
                                    </div>}
                                </div>
                            })}
                            {subjectCount === 0 || subStructure[subjectCount - 1].id > 0 ? <Button key={"add-more-subject"} 
                                onClick={pushNewSubjectEntry} disabled={pageState.buttonLoading}
                                type='primary' icon={<PlusOutlined />}>Add Subject</Button>: null}
                        </div>
                    </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={}>
                                Add Users to Batch
                            </Button> */}
                        </div>
                    )}
                </div>
            {/* </Layout> */}
        </Layout.Content>
    );
}

export default CreateClass;
