import { Cache } from "react-native-cache";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";

type language_t = string;

const cache = new Cache({
    namespace: "translation_terrace",
    policy: {
        maxEntries: 50000, // if unspecified, it can have unlimited entries
        stdTTL: 0 // the standard ttl as number in seconds, default: 0 (unlimited)
    },
    backend: AsyncStorage
});

export type language_matrix_entry = {
    code: string,
    name: string,
    targets: string []
}

export type language_matrix = {
    [key:string] : language_matrix_entry
}

export class Translator {
    constructor(public source : language_t, public defaultTarget : string = "en", private baseUrl = LIBRETRANSLATE_BASE_URL) {
    }

    async fetchLanguages() : Promise<language_matrix> {
        const res = await fetch(this.baseUrl + "/languages", {
            headers: {
                "Content-Type": "application/json"
            }
        });
        const data = await res.json();
        return Object.fromEntries(
            Object.values(data).map((obj : language_matrix_entry) => {
                return [
                    obj["code"],
                    obj,
                ]
            })
        )
    }

    async translate(text : string, target : string|undefined = undefined) {
        const url = LIBRETRANSLATE_BASE_URL + `/translate`;
        const res = await fetch(url, {
            method: "POST",
            body: JSON.stringify({
                q: text,
                source: this.source,
                target: target || this.defaultTarget,
                format: "text",
                alternatives: 3,
                api_key: ""
            }),
            headers: { "Content-Type": "application/json" }
        });
        
        const data = await res.json();
        return data.translatedText
    }
}

export class CachedTranslator extends Translator {
    async translate (text : string, target : string|undefined = undefined) {
        const targetKey = target || this.defaultTarget;
        // console.debug(`Translating from ${this.source} -> ${targetKey}`)
        const key1 = `${this.source}::${targetKey}::${text}`
        const tr1 = await cache.get(key1);
        if (tr1) return tr1;
        const tr2 = await super.translate(text, target);
        const key2 = `${this.source}::${targetKey}::${text}`
        await cache.set(key2, tr2);
    }
}