import User from '../models/community/user.js';
import UserParam from '../models/community/user_param.js';
import UserRight from '../models/community/user_right.js';
import UserRightType from '../models/type/user_right.js';
import UserParamType from '../models/type/user_param.js';
import FalukantUser from '../models/falukant/data/user.js';
import VocabService from '../services/vocabService.js';

const menuStructure = {
    home: {
        visible: ["all"],
        children: {},
        path: "/",
        icon: "logo_mono.png"
    },
    friends: {
        visible: ["all"],
        children: {
            manageFriends: {
                visible: ["all"],
                path: "/friends",
                icon: "friends24.png"
            }
        },
        showLoggedinFriends: 1,
        icon: "friends24.png"
    },
    socialnetwork: {
        visible: ["all"],
        icon: "socialnetwork.png",
        children: {
            guestbook: {
                visible: ["all"],
                path: "/socialnetwork/guestbook"
            },
            blog: {
                visible: ["all"],
                path: "/blogs"
            },
            usersearch: {
                visible: ["all"],
                path: "/socialnetwork/search"
            },
            forum: {
                visible: ["all"],
                path: "/socialnetwork/forum",
                showForums: 1
            },
            gallery: {
                visible: ["all"],
                path: "/socialnetwork/gallery"
            },
            vocabtrainer: {
                visible: ["all"],
                path: "/socialnetwork/vocab",
                children: {}
            },
            blockedUsers: {
                visible: ["all"],
                path: "/socialnetwork/blocked"
            },
            oneTimeInvitation: {
                visible: ["all"],
                path: "/socialnetwork/onetimeinvitation"
            },
            diary: {
                visible: ["all"],
                path: "/socialnetwork/diary"
            },
            erotic: {
                visible: ["over18"],
                children: {
                    pictures: {
                        visible: ["over18"],
                        path: "/socialnetwork/erotic/pictures"
                    },
                    videos: {
                        visible: ["over18"],
                        path: "/socialnetwork/erotic/videos"
                    }
                }
            }
        }
    },
    chats: {
        visible: ["over12"],
        icon: "chat.png",
        children: {
            multiChat: {
                visible: ["over12"],
                action: "openMultiChat",
                view: "window",
                class: "multiChatDialog",
                icon: "multichat24.png"
            },
            randomChat: {
                visible: ["over12"],
                action: "openRanomChat",
                view: "window",
                class: "randomChatDialog"
            },
            eroticChat: {
                visible: ["over18"],
                action: "openEroticChat",
                view: "window",
                class: "eroticChatWindow"
            }
        }
    },
    falukant: {
        visible: ["all"],
        icon: "falukant16.png",
        children: {
            create: {
                visible: ["nofalukantaccount"],
                path: "/falukant/create"
            },
            overview: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/home"
            },
            towns: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/branch"
            },
            family: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/family"
            },
            house: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/house"
            },
            nobility: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/nobility"
            },
            church: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/church"
            },
            politics: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/politics"
            },
            education: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/education"
            },
            health: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/health"
            },
            bank: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/bank"
            },
            darknet: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/darknet"
            },
            reputation: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/reputation"
            },
            moneyhistory: {
                visible: ["hasfalukantaccount"],
                path: "/falukant/moneyhistory"
            }
        }
    },
    minigames: {
        visible: ["all"],
        icon: "minigames16.png",
        children: {
            match3: {
                visible: ["all"],
                path: "/minigames/match3"
            },
            taxi: {
                visible: ["all"],
                path: "/minigames/taxi"
            }
        } 
    },
    settings: {
        visible: ["all"],
        icon: "settings16.png",
        children: {
            homepage: {
                visible: ["all"],
                path: "/settings/homepage"
            },
            account: {
                visible: ["all"],
                path: "/settings/account"
            },
            personal: {
                visible: ["all"],
                path: "/settings/personal"
            },
            view: {
                visible: ["all"],
                path: "/settings/view"
            },
            interests: {
                visible: ["all"],
                path: "/settings/interests"
            },
            flirt: {
                visible: ["over14"],
                path: "/settings/flirt"
            },
            sexuality: {
                visible: ["over14"],
                path: "/settings/sexuality"
            },
            notifications: {
                visible: ["all"],
                path: "/settings/notifications"
            }
        }
    },
    administration: {
        visible: ["anyadmin"],
        children: {
            contactrequests: {
                visible: ["mainadmin", "contactrequests"],
                path: "/admin/contacts"
            },
            users: {
                visible: ["mainadmin", "useradministration"],
                children: {
                    userlist: {
                        visible: ["mainadmin", "useradministration"],
                        path: "/admin/users"
                    },
                    userstatistics: {
                        visible: ["mainadmin"],
                        path: "/admin/users/statistics"
                    },
                    userrights: {
                        visible: ["mainadmin", "rights"],
                        path: "/admin/rights"
                    }
                }
            },
            forum: {
                visible: ["mainadmin", "forum"],
                path: "/admin/forum"
            },
            chatrooms: {
                visible: ["mainadmin", "chatrooms"],
                path: "/admin/chatrooms"
            },
            servicesStatus: {
                visible: ["mainadmin"],
                path: "/admin/services/status"
            },
            interests: {
                visible: ["mainadmin", "interests"],
                path: "/admin/interests"
            }, 
            falukant: {
                visible: ["mainadmin", "falukant"],
                children: {
                    logentries: {
                        visible: ["mainadmin", "falukant"],
                        path: "/admin/falukant/logentries"
                    },
                    edituser: {
                        visible: ["mainadmin", "falukant"],
                        path: "/admin/falukant/edituser"
                    },
                    database: {
                        visible: ["mainadmin", "falukant"],
                        path: "/admin/falukant/database"
                    },
                    mapEditor: {
                        visible: ["mainadmin", "falukant"],
                        path: "/admin/falukant/map"
                    },
                    createNPC: {
                        visible: ["mainadmin", "falukant"],
                        path: "/admin/falukant/create-npc"
                    },
                }
            },
            minigames: {
                visible: ["mainadmin", "match3"],
                children: {
                    match3: {
                        visible: ["mainadmin", "match3"],
                        path: "/admin/minigames/match3"
                    },
                    taxiTools: {
                        visible: ["mainadmin", "taxi"],
                        path: "/admin/minigames/taxi-tools"
                    }
                }
            }
        }
    }
};

class NavigationController {
    constructor() {
        this.menu = this.menu.bind(this);
        this.vocabService = new VocabService();
    }

    calculateAge(birthDate) {
        const today = new Date();
        const birthDateObj = new Date(birthDate);
        let age = today.getFullYear() - birthDateObj.getFullYear();
        const monthDiff = today.getMonth() - birthDateObj.getMonth();
        if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDateObj.getDate())) {
            age--;
        }
        return age;
    }

    async filterMenu(menu, rights, age, userId) {
        const filteredMenu = {};
        try {
            const hasFalukantAccount = await this.hasFalukantAccount(userId);
            for (const [key, value] of Object.entries(menu)) {
                if (value.visible.includes("all")
                    || value.visible.some(v => rights.includes(v)) || (value.visible.includes("anyadmin") && rights.length > 0)
                    || (value.visible.includes("over14") && age >= 14)
                    || (value.visible.includes("over12") && age >= 12)
                    || (value.visible.includes("over18") && age >= 18)
                    || (value.visible.includes('nofalukantaccount') && !hasFalukantAccount)
                    || (value.visible.includes('hasfalukantaccount') && hasFalukantAccount)) {
                    const { visible, ...itemWithoutVisible } = value;
                    filteredMenu[key] = { ...itemWithoutVisible };
                    if (value.children) {
                        filteredMenu[key].children = await this.filterMenu(value.children, rights, age, userId);
                    }
                }
            }
        } catch (error) {
            console.error('Error filtering menu:', error);
            // Return empty menu if filtering fails
            return {};
        }
        return filteredMenu;
    }

    async menu(req, res) {
        try {
            const { userid } = req.params;
            const user = await User.findOne({ where: { hashedId: userid } });
            if (!user) {
                return res.status(404).json({ error: 'User not found' });
            }
            const userRights = await UserRight.findAll({
                where: { userId: user.id },
                include: [{
                    model: UserRightType,
                    as: 'rightType',
                    required: false
                }]
            });
            const userBirthdateParams = await UserParam.findAll({
                where: { userId: user.id },
                include: [
                    {
                        model: UserParamType,
                        as: 'paramType',
                        where: { description: 'birthdate' }
                    }
                ]
            });
            const birthDate = userBirthdateParams.length > 0 ? userBirthdateParams[0].value : (new Date()).toDateString();
            const age = this.calculateAge(birthDate);
            const rights = userRights.map(ur => ur.rightType?.title).filter(Boolean);
            const filteredMenu = await this.filterMenu(menuStructure, rights, age, user.id);

            // Dynamisches Submenü: Treffpunkt → Vokabeltrainer → (Neue Sprache + abonnierte/angelegte)
            // Wichtig: "Neue Sprache" soll IMMER sichtbar sein – auch wenn die DB-Abfrage (noch) fehlschlägt.
            if (filteredMenu?.socialnetwork?.children?.vocabtrainer) {
                const children = {
                    newLanguage: { path: '/socialnetwork/vocab/new' },
                };
                try {
                    const langs = await this.vocabService.listLanguagesForMenu(user.id);
                    for (const l of langs) {
                        children[`lang_${l.id}`] = { path: `/socialnetwork/vocab/${l.id}`, label: l.name };
                    }
                } catch (e) {
                    console.warn('[menu] Konnte Vokabeltrainer-Sprachen nicht laden:', e?.message || e);
                }
                filteredMenu.socialnetwork.children.vocabtrainer.children = children;
            }

            res.status(200).json(filteredMenu);
        } catch (error) {
            console.error('Error fetching menu:', error);
            // Return a minimal working menu instead of 500 error
            res.status(200).json({
                home: { path: "/", icon: "logo_mono.png" },
                settings: { path: "/settings", icon: "settings16.png", children: {} }
            });
        }
    }

    async hasFalukantAccount(userId) {
        try {
            const falukantUser = await FalukantUser.findOne({ where: { userId: userId } });
            return falukantUser !== null;
        } catch (error) {
            console.error('Error checking falukant account:', error);
            return false; // Fallback: assume no falukant account if error occurs
        }
    }
}

export default NavigationController;
