import { useEffect, useState } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import CodeMirror from '@uiw/react-codemirror';
import { html } from '@codemirror/lang-html';
import { javascript } from '@codemirror/lang-javascript';
import { php } from '@codemirror/lang-php';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/material.css';
import PrimaryButton from '@/Components/PrimaryButton';
import { Code, Download, Minus, MinusCircle, Plus } from 'react-feather';
import FormGroup from '@/Components/FormGroup';
import InputLabel from '@/Components/InputLabel';
import TextInput from '@/Components/TextInput';
import AddFrameworkModal from '../AppFramework/AddModal';
import axios from 'axios';

interface InstructionsProps {
    instruction_id: number;
    onDelete: (instruction_id: number) => void;
    onUpdate: (instruction_id: number, steps: any[], frameworkID: string) => void;
}

interface Framework {
    id: number;
    framework_name: string;
    version: string;
}

export default function Instructions({ instruction_id, onDelete, onUpdate }: InstructionsProps) {

    const [frameworkID, setFrameworkID] = useState('');

    const [frameworks, setFrameworks] = useState<Framework[]>([]);
    const fetchFrameworks = async () => {
        try {
            const response = await axios.get<Framework[]>(route('frameworks.index'));
            setFrameworks(response.data);
        } catch (error) {
            console.error('Failed to fetch frameworks', error);
        }
    };

    useEffect(() => {
        fetchFrameworks();
    }, []);

    const [isAddFrameworkModalOpen, setIsAddFrameworkModalOpen] = useState(false);
    const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
        const selectedValue = e.target.value;
        setFrameworkID(selectedValue);
        if (selectedValue === "0") {
            setIsAddFrameworkModalOpen(true);
        }
    }

    const [steps, setSteps] = useState<Array<{ title: string, content: string, code: string }>>([]);

    const handleAddStep = () => {
        setSteps([...steps, { title: '', content: '', code: '' }]);
    };

    const handleRemoveStep = (step_id: number) => {
        setSteps(prevSteps => prevSteps.filter((_, index) => index !== step_id));
    };

    const handleTitleChange = (step_id: number, title: string) => {
        const newSteps = [...steps];
        newSteps[step_id].title = title;
        setSteps(newSteps);
        onUpdate(instruction_id, newSteps, frameworkID);
    };

    const handleContentChange = (step_id: number, content: string) => {
        const newSteps = [...steps];
        newSteps[step_id].content = content;
        setSteps(newSteps);
        onUpdate(instruction_id, newSteps, frameworkID);
    };

    const handleCodeChange = (step_id: number, code: string) => {
        const newSteps = [...steps];
        newSteps[step_id].code = code;
        setSteps(newSteps);
        onUpdate(instruction_id, newSteps, frameworkID);
    };

    return (
        <div className="h-full w-full bg-neutral-10 shadow-md my-4 p-6 rounded-lg flex flex-col items-start">
            <div className='flex w-full justify-between items-center'>
                <h1 className="font-bold text-lg text-secondary-main flex items-center my-2">Instructions Editor</h1>
                <button className="btn btn-link text-error-main p-0 no-underline" onClick={() => onDelete(instruction_id)}>
                    <Minus size={20} />
                    Remove Instruction
                </button>
            </div>
            
            <div className='w-full'>
                <FormGroup>
                    <InputLabel htmlFor="frameworkID"><Code className='stroke-neutral-10' /></InputLabel>
                    <label htmlFor="frameworkID" className="ml-2 w-1/4">Application Framework:</label>
                    <select name="frameworkID" id="frameworkID" value={frameworkID} 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>
                        {frameworks.map(framework => (
                            <option key={framework.id} value={framework.id}>
                                {framework.framework_name}
                            </option>
                        ))}
                        <option value="0" className="text-secondary-main font-semibold">Add new framework</option>
                    </select>
                </FormGroup>
            </div>

            <div className='w-full my-4'>
                {steps.map((step, step_id) => (
                    <div key={step_id}>
                        <div className='flex justify-between items-center'>
                            <div className='flex w-full items-center'>
                                <h3 className='font-semibold text-lg w-1/7'>Step {step_id + 1}</h3>
                                <TextInput
                                    id='stepTitle'
                                    name='stepTitle'
                                    value={step.title}
                                    placeholder='Step Title'
                                    autoComplete='off'
                                    required
                                    onChange={(e) => handleTitleChange(step_id, e.target.value)}
                                    className='w-1/4 mx-4'
                                />
                            </div>
                            <button type="button" className="btn btn-link text-error-main p-0 no-underline" onClick={() => handleRemoveStep(step_id)}>
                                <Minus size={20} />
                                Remove Step
                            </button>
                        </div>
                        
                        <p>Textual Instruction:</p>
                        <ReactQuill
                            value={step.content}
                            onChange={(content) => handleContentChange(step_id, content)}
                            className="h-1/2"
                            modules={{
                                toolbar: [
                                    ['bold', 'italic', 'underline'],
                                    [{'list': 'ordered'}, {'list': 'bullet'}],
                                    ['link', 'image', 'video']
                                ]
                            }}
                        />
                        <p className='mt-2'>Code Snippet:</p>
                        <CodeMirror
                            value={step.code}
                            extensions={[php(), javascript(), html()]}
                            onChange={(value) => handleCodeChange(step_id, value)}
                        />
                        <div className="divider divider-neutral-20"></div>
                    </div>
                ))}
            </div>
            
            <PrimaryButton type="button" onClick={handleAddStep} className='w-full'>
                <Plus className='stroke-neutral-10' />
                Add Steps
            </PrimaryButton>

            <AddFrameworkModal show={isAddFrameworkModalOpen} onClose={() => setIsAddFrameworkModalOpen(false)} onFrameworkAdded={fetchFrameworks} />
        </div>
    );
};