'use client';

import {ChangeEvent, useContext, useState} from "react";
import {WorldContext} from "@/context/WorldContext";
import TextInput from "@/components/form/TextInput";
import TexteAreaInput from "@/components/form/TexteAreaInput";
import {WorldElement, WorldProps} from "@/lib/models/World";
import {AlertContext} from "@/context/AlertContext";
import {SessionContext} from "@/context/SessionContext";
import System from "@/lib/models/System";
import InputField from "@/components/form/InputField";
import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext";

interface WorldElementInputProps {
    sectionLabel: string;
    sectionType: string;
}

export default function WorldElementComponent({sectionLabel, sectionType}: WorldElementInputProps) {
    const t = useTranslations();
    const {lang} = useContext<LangContextProps>(LangContext);
    const {worlds, setWorlds, selectedWorldIndex} = useContext(WorldContext);
    const {errorMessage, successMessage} = useContext(AlertContext);
    const {session} = useContext(SessionContext);
    
    const [newElementName, setNewElementName] = useState<string>('');
    
    async function handleRemoveElement(
        section: keyof WorldProps,
        index: number,
    ): Promise<void> {
        try {
            const response: boolean = await System.authDeleteToServer<boolean>('book/world/element/delete', {
                elementId: (worlds[selectedWorldIndex][section] as WorldElement[])[index].id,
            }, session.accessToken, lang);
            if (!response) {
                errorMessage(t("worldSetting.unknownError"))
            }
            const updatedWorlds: WorldProps[] = [...worlds];
            (updatedWorlds[selectedWorldIndex][section] as WorldElement[]).splice(
                index,
                1,
            );
            setWorlds(updatedWorlds);
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.toString());
            } else {
                errorMessage(t("worldElementComponent.errorUnknown"));
            }
        }
    }
    
    async function handleAddElement(section: keyof WorldProps): Promise<void> {
        if (newElementName.trim() === '') {
            errorMessage(t("worldElementComponent.emptyField", {section: sectionLabel}));
            return;
        }
        try {
            const elementId: string = await System.authPostToServer('book/world/element/add', {
                elementType: section,
                worldId: worlds[selectedWorldIndex].id,
                elementName: newElementName,
            }, session.accessToken, lang);
            if (!elementId) {
                errorMessage(t("worldSetting.unknownError"))
                return;
            }
            const updatedWorlds: WorldProps[] = [...worlds];
            (updatedWorlds[selectedWorldIndex][section] as WorldElement[]).push({
                id: elementId,
                name: newElementName,
                description: '',
            });
            setWorlds(updatedWorlds);
            setNewElementName('');
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("worldElementComponent.errorUnknown"));
            }
        }
    }
    
    function handleElementChange(
        section: keyof WorldProps,
        index: number,
        field: keyof WorldElement,
        value: string,
    ): void {
        const updatedWorlds: WorldProps[] = [...worlds];
        const sectionElements = updatedWorlds[selectedWorldIndex][
            section
            ] as WorldElement[];
        sectionElements[index] = {...sectionElements[index], [field]: value};
        setWorlds(updatedWorlds);
    }
    
    return (
        <div className="space-y-4">
            {Array.isArray(worlds[selectedWorldIndex][sectionType as keyof WorldProps]) &&
                (worlds[selectedWorldIndex][sectionType as keyof WorldProps] as WorldElement[]).map(
                    (element: WorldElement, index: number) => (
                        <div key={element.id}
                             className="bg-secondary/30 rounded-xl p-4 border-l-4 border-primary shadow-sm hover:shadow-md transition-all duration-200">
                            <div className="mb-2">
                                <InputField input={<TextInput
                                    value={element.name}
                                    setValue={(e: ChangeEvent<HTMLInputElement>) => handleElementChange(sectionType as keyof WorldProps, index, 'name', e.target.value)}
                                    placeholder={t("worldElementComponent.namePlaceholder", {section: sectionLabel.toLowerCase()})}
                                />}
                                            removeButtonCallBack={(): Promise<void> => handleRemoveElement(sectionType as keyof WorldProps, index)}/>
                            </div>
                            <TexteAreaInput
                                value={element.description}
                                setValue={(e) => handleElementChange(sectionType as keyof WorldProps, index, 'description', e.target.value)}
                                placeholder={t("worldElementComponent.descriptionPlaceholder", {section: sectionLabel.toLowerCase()})}
                            />
                        </div>
                    )
                )
            }
            <InputField input={<TextInput
                value={newElementName}
                setValue={(e: ChangeEvent<HTMLInputElement>): void => setNewElementName(e.target.value)}
                placeholder={t("worldElementComponent.newPlaceholder", {section: sectionLabel.toLowerCase()})}
            />} addButtonCallBack={(): Promise<void> => handleAddElement(sectionType as keyof WorldProps)}/>
        </div>
    );
}