/** @odoo-module **/
import { useEffect, useEnv, useSubEnv } from "@odoo/owl";
import { registry } from "@web/core/registry";

const translateRegistry = registry.category("translate");
const translateContextSymbol = Symbol("translateContext");

class TranslateContext {
    constructor(env, defaultCategories = []) {
        this.env = env;
        this.categories = new Map(defaultCategories.map(cat => [cat, [{}]]));
    }

    activateCategory(category, context) {
        const contexts = this.categories.get(category) || new Set();
        contexts.add(context);
        this.categories.set(category, contexts);
        return () => {
            contexts.delete(context);
            if (!contexts.size) this.categories.delete(category);
        };
    }

    async getItems() {
        return [...this.categories.entries()]
            .flatMap(([category, contexts]) =>
                translateRegistry
                    .category(category)
                    .getAll()
                    .map(factory => factory({ env: this.env, ...Object.assign({}, ...contexts) }))
            )
            .filter(Boolean)
            .sort((a, b) => (a.sequence || 1000) - (b.sequence || 1000));
    }
}

export function createTranslateContext(env, { categories = [] } = {}) {
    return { [translateContextSymbol]: new TranslateContext(env, categories) };
}

export function useOwnTranslateContext({ categories = [] } = {}) {
    useSubEnv(createTranslateContext(useEnv(), { categories }));
}

export function useEnvTranslateContext() {
    const translateContext = useEnv()[translateContextSymbol];
    if (!translateContext) throw new Error("No translate context in environment");
    return translateContext;
}

export function useTranslateCategory(category, context = {}) {
    const env = useEnv();
    if (env.translate) {
        const translateContext = useEnvTranslateContext();
        useEffect(() => translateContext.activateCategory(category, context), () => []);
    }
}