'use client'
import {useCallback, useContext, useEffect, useState} from 'react';
import {
    Attribute,
    CharacterAttributeSection,
    CharacterListResponse,
    CharacterProps,
    isCharacterCategory,
    isCharacterStatus
} from '@/lib/types/character';
import {SeriesCharacterProps} from '@/lib/types/series';
import {SessionContext, SessionContextProps} from '@/context/SessionContext';
import {BookContext, BookContextProps} from '@/context/BookContext';
import {AlertContext, AlertContextProps} from '@/context/AlertContext';
import {LangContext, LangContextProps} from '@/context/LangContext';
import {apiDelete, apiGet, apiPatch, apiPost} from '@/lib/api/client';
import {useTranslations} from '@/lib/i18n';
import {ViewMode} from '@/lib/types/settings';
import {isDesktop} from '@/lib/configs';
import * as tauri from '@/lib/tauri';
import OfflineContext, {OfflineContextType} from '@/context/OfflineContext';

const initialCharacterState: CharacterProps = {
    id: null,
    name: '',
    lastName: '',
    nickname: '',
    age: null,
    gender: '',
    species: '',
    nationality: '',
    status: 'alive',
    category: 'none',
    title: '',
    role: '',
    image: 'https://via.placeholder.com/150',
    biography: '',
    history: '',
    speechPattern: '',
    catchphrase: '',
    residence: '',
    notes: '',
    color: '',
    physical: [],
    psychological: [],
    relations: [],
    skills: [],
    weaknesses: [],
    strengths: [],
    goals: [],
    motivations: [],
    arc: [],
    secrets: [],
    fears: [],
    flaws: [],
    beliefs: [],
    conflicts: [],
    quotes: [],
    distinguishingMarks: [],
    items: [],
    affiliations: [],
};

export interface UseCharactersConfig {
    entityType: 'book' | 'series';
    entityId: string;
}

export interface UseCharactersReturn {
    // State
    characters: CharacterProps[];
    seriesCharacters: SeriesCharacterProps[];
    selectedCharacter: CharacterProps | null;
    toolEnabled: boolean;
    isLoading: boolean;
    isSeriesMode: boolean;
    bookSeriesId: string | null;
    
    // Navigation state
    viewMode: ViewMode;
    characterBackup: CharacterProps | null;
    
    // Actions
    selectCharacter: (character: CharacterProps) => void;
    addNewCharacter: () => void;
    clearSelection: () => void;
    saveCharacter: () => Promise<boolean>;
    deleteCharacter: (characterId: string) => Promise<void>;
    updateCharacterField: (key: keyof CharacterProps, value: string | number | null) => void;
    addAttribute: (section: CharacterAttributeSection, value: Attribute) => Promise<void>;
    removeAttribute: (section: CharacterAttributeSection, index: number, attrId: string) => Promise<void>;
    toggleTool: (enabled: boolean) => Promise<void>;
    importFromSeries: (seriesCharacterId: string) => Promise<void>;
    exportToSeries: () => Promise<void>;
    refreshCharacters: () => Promise<void>;
    refreshSeriesCharacters: () => Promise<void>;
    setSelectedCharacter: React.Dispatch<React.SetStateAction<CharacterProps | null>>;
    
    // Navigation actions
    enterDetailMode: (character: CharacterProps) => void;
    enterEditMode: () => void;
    exitEditMode: (save: boolean) => Promise<void>;
    backToList: () => void;
}

export function useCharacters(config: UseCharactersConfig): UseCharactersReturn {
    const {entityType, entityId} = config;
    const t = useTranslations();
    const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
    const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
    const {book, setBook}: BookContextProps = useContext<BookContextProps>(BookContext);
    const {errorMessage, successMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
    const {isCurrentlyOffline}: OfflineContextType = useContext<OfflineContextType>(OfflineContext);
    
    const [characters, setCharacters] = useState<CharacterProps[]>([]);
    const [seriesCharacters, setSeriesCharacters] = useState<SeriesCharacterProps[]>([]);
    const [selectedCharacter, setSelectedCharacter] = useState<CharacterProps | null>(null);
    const [toolEnabled, setToolEnabled] = useState<boolean>(entityType === 'series' || (book?.tools?.characters ?? false));
    const [isLoading, setIsLoading] = useState<boolean>(true);
    
    // Navigation state
    const [viewMode, setViewMode] = useState<ViewMode>('list');
    const [characterBackup, setCharacterBackup] = useState<CharacterProps | null>(null);
    
    const isSeriesMode: boolean = entityType === 'series';
    const bookSeriesId: string | null = book?.seriesId || null;
    const userToken: string = session?.accessToken || '';
    
    // Load characters on mount
    useEffect(function (): void {
        if (entityId) {
            refreshCharacters();
        }
    }, [entityId]);
    
    // Load series characters for book mode
    useEffect(function (): void {
        if (bookSeriesId && !isSeriesMode) {
            refreshSeriesCharacters();
        }
    }, [bookSeriesId, isSeriesMode]);
    
    const refreshSeriesCharacters = useCallback(async function (): Promise<void> {
        if (!bookSeriesId) return;
        try {
            const response: SeriesCharacterProps[] = await apiGet<SeriesCharacterProps[]>('series/character/list', userToken, lang, {
                seriesid: bookSeriesId
            });
            if (response) {
                setSeriesCharacters(response);
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            }
        }
    }, [bookSeriesId, userToken, lang]);
    
    const refreshCharacters = useCallback(async function (): Promise<void> {
        setIsLoading(true);
        try {
            if (isSeriesMode) {
                const response: SeriesCharacterProps[] = await apiGet<SeriesCharacterProps[]>(
                    'series/character/list',
                    userToken,
                    lang,
                    {seriesid: entityId}
                );
                if (response) {
                    const mappedCharacters: CharacterProps[] = response.map(function (char: SeriesCharacterProps): CharacterProps {
                        return {
                            id: char.id,
                            name: char.name,
                            lastName: char.lastName || '',
                            nickname: '',
                            age: char.age ?? null,
                            gender: '',
                            species: '',
                            nationality: '',
                            status: char.status && isCharacterStatus(char.status) ? char.status : 'alive',
                            category: isCharacterCategory(char.category) ? char.category : 'none',
                            title: '',
                            role: char.role || '',
                            image: char.image || 'https://via.placeholder.com/150',
                            color: char.color || '',
                            physical: [],
                            psychological: [],
                            relations: [],
                            skills: [],
                            weaknesses: [],
                            strengths: [],
                            goals: [],
                            motivations: [],
                            arc: [],
                            secrets: [],
                            fears: [],
                            flaws: [],
                            beliefs: [],
                            conflicts: [],
                            quotes: [],
                            distinguishingMarks: [],
                            items: [],
                            affiliations: [],
                        };
                    });
                    setCharacters(mappedCharacters);
                }
            } else {
                let response: CharacterListResponse;
                if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                    response = await tauri.getCharacterList(entityId, book?.tools?.characters ?? false) as CharacterListResponse;
                } else {
                    response = await apiGet<CharacterListResponse>('character/list', userToken, lang, {bookid: entityId});
                }
                if (response) {
                    setCharacters(response.characters);
                    setToolEnabled(response.enabled);
                    if (setBook && book) {
                        setBook({
                            ...book,
                            tools: {
                                characters: response.enabled,
                                worlds: book.tools?.worlds ?? false,
                                locations: book.tools?.locations ?? false,
                                spells: book.tools?.spells ?? false
                            }
                        });
                    }
                }
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("common.unknownError"));
            }
        } finally {
            setIsLoading(false);
        }
    }, [entityId, isSeriesMode, userToken, lang, book, setBook, errorMessage, t]);
    
    const selectCharacter = useCallback(function (character: CharacterProps): void {
        setSelectedCharacter({...character});
    }, []);
    
    const addNewCharacter = useCallback(function (): void {
        setSelectedCharacter({...initialCharacterState});
        setViewMode('edit');
        setCharacterBackup(null);
    }, []);
    
    const clearSelection = useCallback(function (): void {
        setSelectedCharacter(null);
        setViewMode('list');
        setCharacterBackup(null);
    }, []);
    
    const updateCharacterField = useCallback(function (key: keyof CharacterProps, value: string | number | null): void {
        setSelectedCharacter(function (prev: CharacterProps | null): CharacterProps | null {
            if (!prev) return null;
            return {...prev, [key]: value};
        });
    }, []);
    
    const toggleTool = useCallback(async function (enabled: boolean): Promise<void> {
        if (isSeriesMode) return;
        try {
            let response: boolean;
            if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                response = await tauri.updateBookToolSetting(book?.bookId ?? '', 'characters', enabled);
            } else {
                response = await apiPatch<boolean>('book/tool-setting', {
                    bookId: book?.bookId,
                    toolName: 'characters',
                    enabled: enabled
                }, userToken, lang);
            }
            if (response && setBook && book) {
                setToolEnabled(enabled);
                setBook({
                    ...book,
                    tools: {
                        characters: enabled,
                        worlds: book.tools?.worlds ?? false,
                        locations: book.tools?.locations ?? false,
                        spells: book.tools?.spells ?? false
                    }
                });
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            }
        }
    }, [isSeriesMode, book, setBook, userToken, lang, errorMessage]);
    
    const saveCharacter = useCallback(async function (): Promise<boolean> {
        if (!selectedCharacter) return false;

        if (selectedCharacter.id === null) {
            return await addCharacterInternal(selectedCharacter);
        } else {
            return await updateCharacterInternal(selectedCharacter);
        }
    }, [selectedCharacter]);
    
    async function addCharacterInternal(character: CharacterProps): Promise<boolean> {
        if (!character.name) {
            errorMessage(t("characterComponent.errorNameRequired"));
            return false;
        }
        if (character.category === 'none') {
            errorMessage(t("characterComponent.errorCategoryRequired"));
            return false;
        }
        try {
            let characterId: string;
            if (isSeriesMode) {
                characterId = await apiPost<string>(
                    'series/character/add',
                    {
                        seriesId: entityId,
                        character: {
                            name: character.name,
                            lastName: character.lastName || null,
                            nickname: character.nickname || null,
                            age: character.age || null,
                            gender: character.gender || null,
                            species: character.species || null,
                            nationality: character.nationality || null,
                            status: character.status || null,
                            category: character.category,
                            title: character.title || null,
                            image: character.image || null,
                            role: character.role || null,
                            biography: character.biography || null,
                            history: character.history || null,
                            speechPattern: character.speechPattern || null,
                            catchphrase: character.catchphrase || null,
                            residence: character.residence || null,
                            notes: character.notes || null,
                            color: character.color || null,
                        }
                    },
                    userToken,
                    lang
                );
            } else if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                characterId = await tauri.createCharacter(character, entityId);
            } else {
                characterId = await apiPost<string>('character/add', {
                    bookId: entityId,
                    character: character,
                }, userToken, lang);
            }

            if (!characterId) {
                errorMessage(t("characterComponent.errorAddCharacter"));
                return false;
            }

            const newCharacter: CharacterProps = {...character, id: characterId};
            setCharacters(function (prev: CharacterProps[]): CharacterProps[] {
                return [...prev, newCharacter];
            });
            setSelectedCharacter(null);
            return true;
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("common.unknownError"));
            }
            return false;
        }
    }
    
    async function updateCharacterInternal(character: CharacterProps): Promise<boolean> {
        try {
            let response: boolean;
            if (isSeriesMode) {
                response = await apiPatch<boolean>('series/character/update', {
                    characterId: character.id,
                    character: {
                        id: character.id,
                        name: character.name,
                        lastName: character.lastName || null,
                        nickname: character.nickname || null,
                        age: character.age || null,
                        gender: character.gender || null,
                        species: character.species || null,
                        nationality: character.nationality || null,
                        status: character.status || null,
                        category: character.category,
                        title: character.title || null,
                        image: character.image || null,
                        role: character.role || null,
                        biography: character.biography || null,
                        history: character.history || null,
                        speechPattern: character.speechPattern || null,
                        catchphrase: character.catchphrase || null,
                        residence: character.residence || null,
                        notes: character.notes || null,
                        color: character.color || null,
                    }
                }, userToken, lang);
            } else if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                response = await tauri.updateCharacter(character);
            } else {
                response = await apiPost<boolean>('character/update', {
                    character: character,
                }, userToken, lang);
            }

            if (!response) {
                errorMessage(t("characterComponent.errorUpdateCharacter"));
                return false;
            }
            
            setCharacters(function (prev: CharacterProps[]): CharacterProps[] {
                return prev.map(function (c: CharacterProps): CharacterProps {
                    return c.id === character.id ? character : c;
                });
            });
            setSelectedCharacter(null);
            successMessage(t("characterComponent.successUpdate"));
            return true;
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("common.unknownError"));
            }
            return false;
        }
    }
    
    const deleteCharacter = useCallback(async function (characterId: string): Promise<void> {
        try {
            let response: boolean;
            if (isSeriesMode) {
                response = await apiDelete<boolean>('series/character/delete', {
                    characterId: characterId,
                }, userToken, lang);
            } else if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                response = await tauri.deleteCharacter(characterId, book?.bookId ?? '', Date.now());
            } else {
                response = await apiDelete<boolean>('character/delete', {
                    characterId: characterId,
                }, userToken, lang);
            }
            
            if (!response) {
                errorMessage(t("characterComponent.errorDeleteCharacter"));
                return;
            }
            
            setCharacters(function (prev: CharacterProps[]): CharacterProps[] {
                return prev.filter(function (c: CharacterProps): boolean {
                    return c.id !== characterId;
                });
            });
            setSelectedCharacter(null);
            successMessage(t("characterComponent.successDelete"));
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("common.unknownError"));
            }
        }
    }, [isSeriesMode, userToken, lang, errorMessage, successMessage, t]);
    
    const addAttribute = useCallback(async function (section: CharacterAttributeSection, value: Attribute): Promise<void> {
        if (!selectedCharacter) return;

        if (selectedCharacter.id === null) {
            const updatedSection: Attribute[] = [
                ...selectedCharacter[section],
                value,
            ];
            setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
        } else {
            try {
                let attributeId: string;
                if (isSeriesMode) {
                    attributeId = await apiPost<string>('series/character/attribute/add', {
                        characterId: selectedCharacter.id,
                        type: section,
                        name: value.name,
                    }, userToken, lang);
                } else if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                    attributeId = await tauri.addCharacterAttribute(selectedCharacter.id, section, value.name);
                } else {
                    attributeId = await apiPost<string>('character/attribute/add', {
                        characterId: selectedCharacter.id,
                        type: section,
                        name: value.name,
                    }, userToken, lang);
                }
                
                if (!attributeId) {
                    errorMessage(t("characterComponent.errorAddAttribute"));
                    return;
                }
                
                const newValue: Attribute = {
                    name: value.name,
                    id: attributeId,
                };
                const updatedSection: Attribute[] = [...selectedCharacter[section], newValue];
                setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
            } catch (e: unknown) {
                if (e instanceof Error) {
                    errorMessage(e.message);
                } else {
                    errorMessage(t("common.unknownError"));
                }
            }
        }
    }, [selectedCharacter, isSeriesMode, userToken, lang, errorMessage, t]);
    
    const removeAttribute = useCallback(async function (section: CharacterAttributeSection, index: number, attrId: string): Promise<void> {
        if (!selectedCharacter) return;

        if (selectedCharacter.id === null) {
            const updatedSection: Attribute[] = selectedCharacter[section].filter(function (_: Attribute, i: number): boolean {
                return i !== index;
            });
            setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
        } else {
            try {
                let response: boolean;
                if (isSeriesMode) {
                    response = await apiDelete<boolean>('series/character/attribute/delete', {
                        attributeId: attrId,
                    }, userToken, lang);
                } else if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                    response = await tauri.deleteCharacterAttribute(attrId, book?.bookId ?? '', Date.now());
                } else {
                    response = await apiDelete<boolean>('character/attribute/delete', {
                        attributeId: attrId,
                    }, userToken, lang);
                }
                
                if (!response) {
                    errorMessage(t("characterComponent.errorRemoveAttribute"));
                    return;
                }
                
                const updatedSection: Attribute[] = selectedCharacter[section].filter(function (_: Attribute, i: number): boolean {
                    return i !== index;
                });
                setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
            } catch (e: unknown) {
                if (e instanceof Error) {
                    errorMessage(e.message);
                } else {
                    errorMessage(t("common.unknownError"));
                }
            }
        }
    }, [selectedCharacter, isSeriesMode, userToken, lang, errorMessage, t]);
    
    const exportToSeries = useCallback(async function (): Promise<void> {
        if (!selectedCharacter || !bookSeriesId) return;
        
        try {
            const seriesCharacterId: string = await apiPost<string>(
                'series/character/add',
                {
                    seriesId: bookSeriesId,
                    character: {
                        name: selectedCharacter.name,
                        lastName: selectedCharacter.lastName || null,
                        nickname: selectedCharacter.nickname || null,
                        age: selectedCharacter.age || null,
                        gender: selectedCharacter.gender || null,
                        species: selectedCharacter.species || null,
                        nationality: selectedCharacter.nationality || null,
                        status: selectedCharacter.status || null,
                        category: selectedCharacter.category,
                        title: selectedCharacter.title || null,
                        image: selectedCharacter.image || null,
                        role: selectedCharacter.role || null,
                        biography: selectedCharacter.biography || null,
                        history: selectedCharacter.history || null,
                        speechPattern: selectedCharacter.speechPattern || null,
                        catchphrase: selectedCharacter.catchphrase || null,
                        residence: selectedCharacter.residence || null,
                        notes: selectedCharacter.notes || null,
                        color: selectedCharacter.color || null,
                    }
                },
                userToken,
                lang
            );
            
            if (seriesCharacterId) {
                const updateResponse: boolean = await apiPost<boolean>('character/update', {
                    character: {
                        ...selectedCharacter,
                        seriesCharacterId: seriesCharacterId
                    },
                }, userToken, lang);
                
                if (updateResponse) {
                    setSelectedCharacter({...selectedCharacter, seriesCharacterId: seriesCharacterId});
                    setCharacters(function (prev: CharacterProps[]): CharacterProps[] {
                        return prev.map(function (c: CharacterProps): CharacterProps {
                            return c.id === selectedCharacter.id ? {...c, seriesCharacterId: seriesCharacterId} : c;
                        });
                    });
                    const newSeriesCharacter: SeriesCharacterProps = {
                        id: seriesCharacterId,
                        name: selectedCharacter.name,
                        lastName: selectedCharacter.lastName || null,
                        nickname: selectedCharacter.nickname || null,
                        age: selectedCharacter.age || null,
                        gender: selectedCharacter.gender || null,
                        species: selectedCharacter.species || null,
                        nationality: selectedCharacter.nationality || null,
                        status: selectedCharacter.status || null,
                        category: selectedCharacter.category,
                        title: selectedCharacter.title || null,
                        image: selectedCharacter.image || null,
                        role: selectedCharacter.role || null,
                        biography: selectedCharacter.biography || null,
                        history: selectedCharacter.history || null,
                        speechPattern: selectedCharacter.speechPattern || null,
                        catchphrase: selectedCharacter.catchphrase || null,
                        residence: selectedCharacter.residence || null,
                        notes: selectedCharacter.notes || null,
                        color: selectedCharacter.color || null,
                    };
                    setSeriesCharacters(function (prev: SeriesCharacterProps[]): SeriesCharacterProps[] {
                        return [...prev, newSeriesCharacter];
                    });
                    successMessage(t("characterComponent.exportSuccess"));
                }
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            }
        }
    }, [selectedCharacter, bookSeriesId, userToken, lang, successMessage, errorMessage, t]);
    
    const importFromSeries = useCallback(async function (seriesCharacterId: string): Promise<void> {
        const seriesChar: SeriesCharacterProps | undefined = seriesCharacters.find(function (c: SeriesCharacterProps): boolean {
            return c.id === seriesCharacterId;
        });
        if (!seriesChar) return;
        
        try {
            const characterToImport: CharacterProps = {
                id: null,
                name: seriesChar.name,
                lastName: seriesChar.lastName || '',
                nickname: seriesChar.nickname || '',
                age: seriesChar.age ?? null,
                gender: seriesChar.gender || '',
                species: seriesChar.species || '',
                nationality: seriesChar.nationality || '',
                status: seriesChar.status && isCharacterStatus(seriesChar.status) ? seriesChar.status : 'alive',
                category: isCharacterCategory(seriesChar.category) ? seriesChar.category : 'none',
                title: seriesChar.title || '',
                role: seriesChar.role || '',
                image: seriesChar.image || 'https://via.placeholder.com/150',
                biography: seriesChar.biography || '',
                history: seriesChar.history || '',
                speechPattern: seriesChar.speechPattern || '',
                catchphrase: seriesChar.catchphrase || '',
                residence: seriesChar.residence || '',
                notes: seriesChar.notes || '',
                color: seriesChar.color || '',
                physical: [],
                psychological: [],
                relations: [],
                skills: [],
                weaknesses: [],
                strengths: [],
                goals: [],
                motivations: [],
                arc: [],
                secrets: [],
                fears: [],
                flaws: [],
                beliefs: [],
                conflicts: [],
                quotes: [],
                distinguishingMarks: [],
                items: [],
                affiliations: [],
                seriesCharacterId: seriesCharacterId,
            };
            
            let characterId: string;
            if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                characterId = await tauri.createCharacter(characterToImport, entityId);
            } else {
                characterId = await apiPost<string>('character/add', {
                    bookId: entityId,
                    character: characterToImport,
                }, userToken, lang);
            }
            
            if (!characterId) {
                errorMessage(t("characterComponent.importError"));
                return;
            }
            
            characterToImport.id = characterId;
            setCharacters(function (prev: CharacterProps[]): CharacterProps[] {
                return [...prev, characterToImport];
            });
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            }
        }
    }, [seriesCharacters, entityId, userToken, lang, errorMessage, successMessage, t]);
    
    // Navigation functions
    const enterDetailMode = useCallback(function (character: CharacterProps): void {
        setSelectedCharacter({...character});
        setViewMode('detail');
        setCharacterBackup(null);
    }, []);
    
    const enterEditMode = useCallback(function (): void {
        if (selectedCharacter) {
            setCharacterBackup({...selectedCharacter});
        }
        setViewMode('edit');
    }, [selectedCharacter]);
    
    const exitEditMode = useCallback(async function (save: boolean): Promise<void> {
        if (save) {
            const success: boolean = await saveCharacter();
            if (!success) return;
            if (characterBackup) {
                setViewMode('detail');
            } else {
                setViewMode('list');
            }
        } else {
            if (characterBackup) {
                setSelectedCharacter(characterBackup);
                setViewMode('detail');
            } else {
                setSelectedCharacter(null);
                setViewMode('list');
            }
        }
        setCharacterBackup(null);
    }, [saveCharacter, characterBackup]);
    
    const backToList = useCallback(function (): void {
        setSelectedCharacter(null);
        setCharacterBackup(null);
        setViewMode('list');
    }, []);
    
    return {
        // State
        characters,
        seriesCharacters,
        selectedCharacter,
        toolEnabled,
        isLoading,
        isSeriesMode,
        bookSeriesId,
        
        // Navigation state
        viewMode,
        characterBackup,
        
        // Actions
        selectCharacter,
        addNewCharacter,
        clearSelection,
        saveCharacter,
        deleteCharacter,
        updateCharacterField,
        addAttribute,
        removeAttribute,
        toggleTool,
        importFromSeries,
        exportToSeries,
        refreshCharacters,
        refreshSeriesCharacters,
        setSelectedCharacter,
        
        // Navigation actions
        enterDetailMode,
        enterEditMode,
        exitEditMode,
        backToList,
    };
}
