import FormGroup from "@/Components/FormGroup";
import InputError from "@/Components/InputError";
import InputLabel from "@/Components/InputLabel";
import TextInput from "@/Components/TextInput";
import Authenticated from "@/Layouts/AuthenticatedLayout";
import { PageProps } from "@/types";
import { Head, Link, useForm } from "@inertiajs/react";
import { Book, Box, CheckCircle, FileText, Paperclip, Plus, PlusCircle, XCircle, XOctagon } from "react-feather";
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/javascript/javascript';
import PrimaryButton from "@/Components/PrimaryButton";
import Instructions from "./InstructionsForm";
import Modal from "@/Components/Modal";
import ModalButton from "@/Components/ModalButton";
import { FormEventHandler, useEffect, useState } from "react";
import AddCategoryModal from "../SubjectCategory/AddModal";
import axios from "axios";
import SuccessButton from "@/Components/SuccessButton";
import ErrorButton from "@/Components/ErrorButton";
import dayjs from "dayjs";

interface Category {
    id: number;
    subject_title: string;
    description?: string;
}

export default function Create({ auth }: PageProps) {
    const thisUser = auth.user;

    const { data, setData, processing, errors } = useForm({
        pageTitle: '',
        category: '',
        introduction:'',
    });

    const [isAddCategoryModalOpen, setIsAddCategoryModalOpen] = useState(false);
    const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
        const selectedValue = e.target.value;
        setData('category', selectedValue);
        if (selectedValue === "0") {
            setIsAddCategoryModalOpen(true);
        }
    }

    const [status, setStatus] = useState('');
    const [feedback, setFeedback] = useState('');
    const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false);
    const [isErrorModalOpen, setIsErrorModalOpen] = useState(false);
    const [categories, setCategories] = useState<Category[]>([]);

    const fetchCategories = async () => {
        try {
            const response = await axios.get<Category[]>(route('categories.index'));
            setCategories(response.data);
        } catch (e) {
            setStatus('Function Failure');
            setFeedback('Failed to fetch categories');
            setIsErrorModalOpen(true);
        }
    };

    useEffect(() => {
        if (thisUser.role_id !== 1) {
            setStatus('Warning');
            setFeedback('You are unauthorized to access this page');
            setIsErrorModalOpen(true);
        } else {
            fetchCategories();
        }
    }, [thisUser.role_id]);

    const handleCloseSuccessModal = () => {
        setIsSuccessModalOpen(false);
        window.location.href = '/dashboard';
    }

    const handleCloseErrorModal = () => {
        setIsErrorModalOpen(false);
        window.location.href = '/dashboard';
    };

    const [instructions, setInstructions] = useState<{ id: number; steps: any[]; frameworkID: string; }[]>([]);
    const [nextId, setNextId] = useState<number>(0);
    const handleAddInstruction = () => {
        setInstructions([...instructions, { id: nextId, steps: [], frameworkID: '' }]);
        setNextId(nextId + 1);
    };
    const handleRemoveInstruction = (id: number) => {
        setInstructions(prevInstructions =>
            prevInstructions.filter(instruction => instruction.id !== id)
        );
    };
    const handleUpdateInstruction = (id: number, steps: any[], frameworkID: string) => {
        setInstructions(prevInstructions =>
            prevInstructions.map(instruction =>
                instruction.id === id ? { ...instruction, steps, frameworkID } : instruction
            )
        );
    };

    const submit: FormEventHandler = async (e) => {
        e.preventDefault();

        if (data.category==="0" || data.category==="") {
            alert('Please choose a valid category.')
            return
        }

        try {
            const response = await axios.post(route('page.add'), data);
            const pageID = response.data.page.id;

            await Promise.all(instructions.map(async (instruction) => {
                if (instruction.frameworkID === "0" || instruction.frameworkID === "") {
                    alert('Please choose a valid framework for each instruction.');
                    return;
                }

                const timestamp = dayjs().format('YYYYMMDDHHmmss');
                const jsonString = JSON.stringify({ steps: instruction.steps });
                const blob = new Blob([jsonString], { type: 'application/json' });
                const file = new File([blob], `${timestamp}.json`, { type: 'application/json' });

                const formData = new FormData();
                formData.append('file', file);
                formData.append('frameworkID', instruction.frameworkID);
                formData.append('pageID', pageID.toString());

                await axios.post(route('instruction.add'), formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data',
                    },
                });
            }));

            setStatus('Success');
            setFeedback(response.data.message);
            setIsSuccessModalOpen(true);
        } catch (error) {
            setStatus('Error')
            if (axios.isAxiosError(error)) {
                setFeedback(error.response?.data.message || 'An error occurred');
            } else {
                setFeedback('An unexpected error occurred');
            }
            setIsErrorModalOpen(true);
        }
    }

    const renderIfAdmin = () => {
        if (thisUser.role_id === 1) {
            return (
                <div>
                    <div className="breadcrumbs text-sm">
                        <ul>
                            <li><Link href="/dashboard">Home</Link></li>
                            <li><a>Repository Pages</a></li>
                            <li>Add New Repository Page</li>
                        </ul>
                    </div>

                    <h1 className="font-bold text-xl text-primary-main flex items-center my-2"><FileText className="stroke-primary-main mr-2" />Create Repository Page</h1>
                    <div className="divider"></div>
                    <form id="CreateRepositoryPageForm" onSubmit={submit}>
                        <div>
                            <FormGroup>
                                <InputLabel htmlFor="pageTitle"><Box className='stroke-neutral-10' /></InputLabel>
                                <label htmlFor="pageTitle" className="mx-2 font-semibold">Page Title:</label>
                                
                            </FormGroup>
                            <TextInput
                                    id='pageTitle'
                                    name='pageTitle'
                                    value={data.pageTitle}
                                    autoComplete='off'
                                    required
                                    onChange={(e) => setData('pageTitle', e.target.value)}
                                />
                            <InputError message={errors.pageTitle} className="mt-2" />
                        </div>
                        
                        <div>
                        <FormGroup>
                            <InputLabel htmlFor="category"><Book className='stroke-neutral-10' /></InputLabel>
                            <label htmlFor="category" className="mx-2 font-semibold">Subject Category:</label>
                        </FormGroup>
                        <select name="category" id="category" value={data.category} onChange={handleChange}
                            className='px-2 py-0 flex-grow w-full h-[30px] bg-primary-background border border-primary-hover focus:outline-none focus:bg-neutral-10 focus:border focus:border-primary-hover'>
                                <option value="" selected disabled></option>
                                {categories.map(category => (
                                    <option key={category.id} value={category.id}>
                                        {category.subject_title}
                                    </option>
                                ))}
                                <option value="0" className="text-secondary-main font-semibold">Add new framework</option>
                        </select>
                        </div>
                        
                        <div>
                            <FormGroup>
                                <InputLabel htmlFor="description"><Paperclip className='stroke-neutral-10' /></InputLabel>
                                <label htmlFor="description" className="mx-2 font-semibold">Introduction:</label>
                            </FormGroup>
                            <textarea className='px-2 flex-grow w-full bg-primary-background border border-primary-hover focus:outline-none focus:bg-neutral-10 focus:border-2 focus:border-primary-hover '
                            onChange={(e) => setData('introduction', e.target.value)} />
                        </div>
                        {instructions.map((instruction) => (
                            <Instructions
                                key={instruction.id}
                                instruction_id={instruction.id}
                                onDelete={handleRemoveInstruction}
                                onUpdate={handleUpdateInstruction}
                            />
                        ))}
                        <PrimaryButton type='button' disabled={processing} onClick={handleAddInstruction} className="w-full">
                            <Plus className='stroke-neutral-10' />
                            Add Instruction
                        </PrimaryButton>
                        
                        <div className="divider"></div>
                        <div className="flex">
                            <ErrorButton className="w-1/2" onClick={() => window.location.href = '/dashboard'}>
                                <XCircle className='stroke-neutral-10' />
                                Cancel
                            </ErrorButton>
                            <SuccessButton type="submit" className="w-1/2">
                                <PlusCircle className='stroke-neutral-10' />
                                Save Repository Page
                            </SuccessButton>
                        </div>
                    </form>
                </div>
            );
        }
    }

    return (
        <Authenticated user={thisUser}>
            <Head title="Repository Page" />

            <div id="CreateRepositoryPage" className="drawer lg:drawer-open">
                <input id="my-drawer-2" type="checkbox" className="drawer-toggle" />
                <div className="drawer-content flex flex-row justify-between p-6 bg-neutral-20">
                    <div className="h-full w-full bg-neutral-10 shadow-md p-6 rounded-lg">
                        {renderIfAdmin()}
                    </div>
                </div>
                <div className="drawer-side">
                    <label htmlFor="my-drawer-2" aria-label="close sidebar" className="drawer-overlay"></label> 
                    
                    <ul className="menu p-4 w-56 h-full bg-primary-background text-base-content">
                        {/* Sidebar content here */}
                        <li><a>Sidebar Item 1</a></li>
                        <li><a>Sidebar Item 2</a></li>
                    </ul>
                </div>
            </div>

            <AddCategoryModal show={isAddCategoryModalOpen} onClose={() => setIsAddCategoryModalOpen(false)} onCategoryAdded={fetchCategories} />

            <Modal show={isSuccessModalOpen} onClose={() => setIsSuccessModalOpen(false)} maxWidth="lg" styling='success'>
                <div className="p-4 flex flex-col items-center">
                    <CheckCircle className='stroke-success-main' size={80} />
                    <h2 className="text-xl font-bold mt-2">{ status }</h2>
                    <p className="mt-4">{ feedback }</p>
                    <ModalButton onClick={handleCloseSuccessModal} className="bg-success-main text-white hover:bg-success-hover active:bg-success-pressed">
                        Close
                    </ModalButton>
                </div>
            </Modal>

            <Modal show={isErrorModalOpen} onClose={() => setIsErrorModalOpen(false)} maxWidth="lg" styling='error'>
                <div className="p-4 flex flex-col items-center">
                    <XOctagon className='stroke-error-main' size={80} />
                    <h2 className="text-xl font-bold mt-2">{ status }</h2>
                    <p className="mt-4">{ feedback }</p>
                    <ModalButton onClick={handleCloseErrorModal} className="bg-error-main text-white hover:bg-error-hover active:bg-error-pressed">
                        Close
                    </ModalButton>
                </div>
            </Modal>
        </Authenticated>
    );
}