import React, { useState, useRef } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Button, Layout, Select, Typography, Radio, notification, Modal, Spin } from 'antd';
import './createNewQuestion.css';
import "quill/dist/quill.snow.css";
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons';
import { selectorService } from '../../services/selectorService';
import { authenticationService } from '../../_services';
import SelectorNew from './SelectorNew';
import QuillToolbar from './createQuestion/RichTextEditorTextBox';
import OptionsRadio from './createQuestion/OptionsRadio';
import OptionsCheckbox from './createQuestion/OptionsCheckbox';
import OptionsBoolean from './createQuestion/OptionsBoolean';
import _ from 'lodash';
import UploadQuestionModal from './uploadQuestion/UploadQuestionModal';

const complexityOptions = [
    {
        label: 'Easy',
        value: 1,
    },
    {
        label: 'Medium',
        value: 2,
    },
    {
        label: 'Difficult',
        value: 3,
    },
];

const CreateQuestion = ({ language }) => {

    const location = useLocation();
    const history = useHistory();

    const [uploadMode, setUploadMode] = useState({isOpen: false});
    const [editResourceLoaded, setEditResourceLoaded] = useState({check: false, mode: 1});

    const [toolbarContainerLoaded, checkToolbarContainerLoad] = useState(false);

    const [submitting, setSubmitting] = useState(false);
    const anchorRef = useRef(); // to catch the title editor to refocus when changing question types and prevent onBlur bug that hiding the editor toolbar causes.

    const cls = useRef(authenticationService.currentClassValue);
    //category about the question
    const [selectorVariables, setSelectorVariables] = useState({
        subject: "",
        category: "", // this is same as topic thats referred to in UI
        questionType: "",
    });

    //properties of the question
    const [properties, setProperties] = useState({
        language: authenticationService.currentUserValue.language_code || "",
        complexity_code: "",
        title: "",
        answer_explanation: ""
    });

    // Data from option boxes
    const actualOptionData = useRef([{text: "", isCorrect: false}, {text: "", isCorrect: false}]);

    const [sectionName, setSectionName] = useState("");  // name of the section

    React.useEffect(() => {
        async function fetchQuestionFromServer () {
            if(location.rowState?.key && location.rowState.status === "DRAFT") {
                setSubmitting(true);    // just to make loading modal show up
                const res = await selectorService.getQuestion(location.rowState.key);
                // console.log(res);
                /*
                    answer_explanation: ""
                    author_id: 80
                    author_name: "EduTech"
                    complexity_code: 2
                    id: 2105
                    isActive: true
                    isBookmarked: null
                    languages_available: Array [ 1 ]
                    last_updated: "2022-11-17T04:59:56.13"
                    options: Array [ {…}, {…} ]
                    source: "Manual Entry"
                    status: "DRAFT"
                    subject_id: 1
                    subject_name: "General Awareness"
                    tags: null
                    title: "<p>In which year was India partitioned?</p>"
                    topic_id: 1
                    topic_name: "History of India"
                    type: "MCQ"
                    type_name: "Multiple Choice Questions"
                */
                setSelectorVariables({
                    subject: res.result.subject_id,
                    category: res.result.topic_id,
                    questionType: res.result.type
                });
                setProperties(prev => ({
                    ...prev,
                    complexity_code: res.result.complexity_code,
                    title: res.result.title,
                    answer_explanation: res.result.answer_explanation
                }));
                actualOptionData.current = res.result.options;

                setSubmitting(false);
                setEditResourceLoaded({check: true, mode: 1});
            } else {
                setSectionName("Please select a question type from dropdown to continue");
                setEditResourceLoaded({check: true, mode: -1});
            }
        }
        fetchQuestionFromServer();
    }, []);

    React.useEffect(() => {
        if (selectorVariables.questionType && anchorRef.current) {
            // anchorRef.current.focus(); // this was an attempt to bring focus to Question Detail editor, but the logic didnt work out in the end so dropped it.
            // But left this code as a future reference if its needed.

            checkToolbarContainerLoad(false);
            setProperties(prev => ({...prev, complexity_code: "", answer_explanation: ""}));
            actualOptionData.current = [{text: "", isCorrect: false}, {text: "", isCorrect: false}];
            setTimeout(() => checkToolbarContainerLoad(true), 100);
        }
        if (!selectorVariables.questionType) {
             checkToolbarContainerLoad(false);
             actualOptionData.current = [{text: "", isCorrect: false}, {text: "", isCorrect: false}];
        }
        if(selectorVariables.questionType && !anchorRef.current) {
            checkToolbarContainerLoad(true);
        }
    }, [selectorVariables.questionType]);

    function handleSelection(property, value = "", objectName = "Please select a question type from dropdown to continue") {
        if (property === "questionType") {
            objectName.children ? setSectionName(objectName?.children)
                : setSectionName("Please select a question type from dropdown to continue");
        }
        setSelectorVariables(prevVal => ({
            ...prevVal,
            [property]: value,
        }));
    }

    function renderOption() {
        switch (selectorVariables.questionType) {
            case "MCQ":
                return <OptionsRadio actualOptionData={actualOptionData} toolbarContainerLoaded={toolbarContainerLoaded} />;
            case "MRQ":
                return <OptionsCheckbox actualOptionData={actualOptionData} toolbarContainerLoaded={toolbarContainerLoaded} />;
            case "TNF":
                return <OptionsBoolean actualOptionData={actualOptionData} />;
            case "SUB":
                return;
            default:
                return <h4>This is messed up bro...</h4>
        }
    }

    function collectInfo(status) {
        let validate;
        // checking if subject and topic and question types are selected from dropdown at the top
        if (!selectorVariables.subject || !selectorVariables.category || !selectorVariables.questionType) {
            status === "PUBLISHED" ? notification.error({ message: "Please select all the options from the dropdown to continue." })
                : notification.error({ message: "Atleast select \"Subject\", \"Topic\" and \"Question Type\" from the dropdown before you save the question to Draft" });
            return;
        }

        if(status === "DRAFT") {    // this check is only meant for question that is being sent to DRAFT status
            if (!properties.title || !properties.language || !properties.complexity_code) {
                notification.error({ message: "Make sure to fill up question detail, and set language and complexity before you save the question to Draft" });
                return;
            }
        }

        if (status === "PUBLISHED") {    // this check is only meant for question which is being published (as in getting Submitted)
            if (!properties.title || !properties.language || !properties.answer_explanation || !properties.complexity_code) {
                notification.error({ message: "Make sure to fill up question detail and explanation, and set language and complexity before continuing" });
                return;
            }
            let s = properties.title;
            let t = s.replace(new RegExp('<[^>]*>', 'g'), ''); // this replaces all HTML tag with "" [empty string]
            t = t.replace(" ", "");
            if (!t) {
                notification.error({ message: "Please fill up question detail before continuing" });
                return;
            }
            s = properties.answer_explanation;
            t = s.replace(new RegExp('<[^>]*>', 'g'), ''); // this replaces all HTML tag with "" [empty string]
            t = t.replace(" ", "");
            if (!t) {
                notification.error({ message: "Please fill up question explanation before continuing" });
                return;
            }
        }

        if (selectorVariables.questionType !== "SUB") {
            // the above condition makes it so that when question type is set to subjective,
            // there will be no check for Options because Subjective questions don't have options.

            validate = actualOptionData.current.filter(item => item.isCorrect);
            // checking if one or more correct answers is/are selected.
            if (validate.length === 0 && status !== "DRAFT") {
                notification.error({ message: "Please select a correct answer first before submitting" });
                return;
            }
            validate = actualOptionData.current.filter(item => (item.text ? true : false));
            // checking if a question exist in all the option blanks created.
            if (validate.length !== actualOptionData.current.length && status !== "DRAFT") {
                notification.error({ message: "Please fill up all the option boxes before submitting" });
                return;
            }

        }
        submit({ ...properties, options: actualOptionData.current, ...selectorVariables, status }); // sending all validated info to submit function now
    }

    async function submit({ questionType: type, category: topic_id, complexity_code, title, answer_explanation, options, status }) {
        // REQUEST BODY
        // {
        //    "type": "string",
        //    "topic_id": 0,
        //    "complexity_code": 0,
        //    "status": "string", // need to add
        //    "title": "string",
        //    "description": "string", // uhhhh???
        //    "answer_explanation": "string",
        //    "source": "string", // need to add
        //    "options": [
        //      {
        //        "text": "string",
        //        "isCorrect": true
        //      }
        //    ]
        // }
        // options not needed in case of SUBJECTIVE question types.

        if (status === "DRAFT" && type !== "SUB") {
            options = options.filter(option => {
                if(option.text) {
                    return true;
                }
            });
        }
        let submitObject;
        submitObject = type !== "SUB" ? { type, topic_id, complexity_code, title, answer_explanation, options, status }
            : { type, topic_id, complexity_code, title, answer_explanation, status };
        submitObject.source = "Manual Entry";
        try {
            setSubmitting(true);

            if (editResourceLoaded.mode === 1) {
                submitObject.id = location.rowState.key;
                const response = await selectorService.editQuestion(location.rowState.key, submitObject);
                if (response.status.code < 0) {
                    throw response.status.message || "Something went wrong, please try again";
                }
                status === "PUBLISHED"? notification.success({ message: "Question successfully published" }) 
                    : notification.success({ message: "Question successfully edited" });
                
                history.push("/draftQuestions");
                // setSubmitting(false);
            }

            if (editResourceLoaded.mode < 0) {
                const response = await selectorService.createQuestion(submitObject);
                if (response.status.code < 0) {
                    throw response.status.message || "Something went wrong, please try again";
                }
                status === "PUBLISHED"? notification.success({ message: "Question successfully published" }) 
                    : notification.success({ message: "Question successfully drafted" });
                setSubmitting(false);

                // reset the inputs after successful submit
                checkToolbarContainerLoad(false);
                setProperties({language: authenticationService.currentUserValue.language_code||"", complexity_code: "", title: "", answer_explanation: ""});
                actualOptionData.current = [{text: "", isCorrect: false}, {text: "", isCorrect: false}];
                setTimeout(() => checkToolbarContainerLoad(true), 100);
            }
        } catch (err) {
            err && notification.error({ message: err });
            setSubmitting(false);
        }
    }

    function openUploadModal() {
        setUploadMode({isOpen: true});
    }

    return (
        <Layout className='overflow-y--ready'>
            {editResourceLoaded.check && <Layout.Content prefixCls='create-question'>
                <div className='section-header'>
                    <div className="left-side">
                        <SelectorNew serviceCall={selectorService.loadSubjects} pathActive={cls.current} handleSelection={handleSelection} property="subject"
                            placeholder="Select a subject" chosenValue={selectorVariables.subject} />
                        <SelectorNew serviceCall={selectorService.loadCategory} pathActive={selectorVariables.subject} handleSelection={handleSelection} property="category"
                            placeholder="Select a topic" chosenValue={selectorVariables.category} />
                        <SelectorNew serviceCall={selectorService.loadQuestionTypes} handleSelection={handleSelection} property="questionType"
                            placeholder="Select the question type" chosenValue={selectorVariables.questionType} />
                    </div>
                    <div className="right-side">
                        <Button type='primary' onClick={() => openUploadModal()} icon={<UploadOutlined />}>
                            Upload Questions
                        </Button>
                    </div>
                </div>
                <div className="section-name">
                    <Typography.Title level={5}>{sectionName}</Typography.Title>
                </div>
                {sectionName !== "Please select a question type from dropdown to continue" && <div className="section-body">
                    <div className="toolbar-section"> </div> {/* this is tracked by toolbarContainerLoaded */}
                    <div className="user-input-section">

                        <Typography.Text className='align--center' strong>Select Language :</Typography.Text>
                        <Select
                            size='normal'
                            // suffixIcon={<CaretDownOutlined />}
                            placeholder="Select language"
                            onChange={value => setProperties(prev => ({ ...prev, language: value }))}
                            value={properties.language || undefined}
                            style={{ minWidth: '150px' }}
                        >
                            {language.map(eachlang => {
                                return <Select.Option key={eachlang.id} value={eachlang.code || eachlang.id}>{eachlang.name}</Select.Option>
                            })}
                        </Select>

                        <Typography.Text className='align--center' strong>Complexity :</Typography.Text>
                        <Radio.Group
                            options={complexityOptions}
                            onChange={({ target: { value } }) => setProperties(prev => ({ ...prev, complexity_code: value }))}
                            value={properties.complexity_code || undefined}
                            optionType="button"
                            buttonStyle="solid"
                        />

                        {toolbarContainerLoaded && <Typography.Text className='align--center' strong>Question Details :</Typography.Text>}
                        {toolbarContainerLoaded && <QuillToolbar
                            anchorRef={anchorRef}
                            defaultValue={properties.title}
                            setProperties={setProperties}
                            placeholder="Write the question..."
                            idTool="detail-1"
                            toolbarContainerLoaded={toolbarContainerLoaded}
                        />}

                        {selectorVariables?.questionType !== "SUB" && toolbarContainerLoaded && <Typography.Text className='pt-1-0' strong>Options :</Typography.Text>}
                        {renderOption()}

                        {toolbarContainerLoaded && <Typography.Text className='pt-1-0' strong>Explanation :</Typography.Text>}
                        {toolbarContainerLoaded && <QuillToolbar
                            defaultValue={properties.answer_explanation}
                            placeholder="Explanation for the answer"
                            setProperties={setProperties}
                            idTool="detail-2"
                            toolbarContainerLoaded={toolbarContainerLoaded}
                        />}
                    </div>
                </div>}
            </Layout.Content>}
            <div className="button-container">
                <Button disabled={submitting} onMouseDown={() => collectInfo("DRAFT")}>Save</Button>
                <Button type='primary' disabled={submitting} onMouseDown={() => collectInfo("PUBLISHED")}>Submit</Button>
            </div>
            <Modal open={submitting} visible={submitting} width={108} maskClosable={false} keyboard={false} closable={false} centered footer={null} >
                <Spin indicator={<LoadingOutlined style={{ fontSize: 60 }} spin />} />
            </Modal>
            
            <div className="upload-question-modal">
                <UploadQuestionModal uploadMode={uploadMode} setUploadMode={setUploadMode} />
            </div>
        </Layout>
    );
}

export default CreateQuestion;
