<script setup lang="ts">
import { ExampleCategory, ExamplePart, Pronoun } from '~/src/classes.ts';
import Compressor from '~/src/compressor.ts';
import { loadPronounExamples, loadPronounLibrary } from '~/src/data.ts';

const config = useConfig();
if (!config.pronouns.enabled || !config.pronouns.generator.enabled) {
    throw new Error('config.pronouns.generator is disabled');
}

const { $translator: translator } = useNuxtApp();

const [pronounLibrary, examples] = await Promise.all([loadPronounLibrary(config), loadPronounExamples()]);
const pronouns = pronounLibrary.pronouns;

const exampleCategories = ExampleCategory.from(examples, config);
const examplesByHonorific = [false, true].map((isHonorific) => {
    const examples = exampleCategories
        .filter((exampleCategory) => !exampleCategory.comprehensive && exampleCategory.examples.length > 0)
        .map((exampleCategory) => exampleCategory.examples[0])
        .filter((example) => example.isHonorific === isHonorific);
    return { examples, isHonorific };
}).filter(({ examples }) => examples.length > 0);

const selectedPronoun = ref(pronouns[config.pronouns.generator.startPronoun].clone(true));
const selectedMorpheme = ref('');

const glue = ` ${translator.translate('pronouns.or')} `;

const clearExampleParts = (parts: ExamplePart[]): ExamplePart[] => {
    return parts.map((p) => new ExamplePart(p.variable, p.str.replace(/^'/, '')));
};

const deduplicatePronounGroup = (pronounGroup: Pronoun[]): Pronoun[] => {
    const dict: Record<string, Pronoun> = {};
    for (const pronoun of pronounGroup) {
        if (Object.hasOwn(dict, pronoun.name(glue))) {
            continue;
        }
        dict[pronoun.name(glue)] = pronoun;
    }
    return Object.values(dict);
};

const usedBase = computed((): string | null => {
    const name = selectedPronoun.value.name(glue);
    for (const key in pronouns) {
        if (Object.hasOwn(pronouns, key)) {
            if (key === name) {
                return key;
            }
            for (const alias of pronouns[key].aliases) {
                if (alias === name) {
                    return key;
                }
            }
        }
    }

    return null;
});
const usedBaseEquals = computed((): boolean => {
    return !!usedBase.value && selectedPronoun.value.equals(pronouns[usedBase.value], true);
});

const longPath = computed((): string => {
    const base = pronouns[selectedPronoun.value.morphemes[config.pronouns.morphemes![0]]!];

    return base
        ? Compressor.compress(
                selectedPronoun.value.toArray().map((x) => x.split('|')[0]),
                base.toArray().map((x) => x.split('|')[0]),
            ).join(',')
        : selectedPronoun.value.toString();
});
const path = computed((): string | null => {
    if (!selectedPronoun.value.pronoun()) {
        return null;
    }

    const slashes = selectedPronoun.value.toStringSlashes(translator);

    if (usedBaseEquals.value) {
        return usedBase.value;
    } else if (slashes) {
        return slashes;
    } else {
        return longPath.value;
    }
});
</script>

<template>
    <PronounsGenerator
        v-if="config.pronouns.enabled && config.pronouns.generator.enabled"
        type="generator"
        :path="path"
        :initially-open="config.pronouns.generator.autoOpen ?? false"
        :disclaimer="!usedBaseEquals"
    >
        <div class="card-title border-bottom pb-3">
            <p><strong><T>home.generator.base</T><T>quotation.colon</T></strong></p>
            <ul class="list-unstyled">
                <template v-for="[group, groupPronouns] in pronounLibrary.split()" :key="group.key">
                    <li v-if="!group.hidden">
                        <ul class="list-inline">
                            <li class="list-inline-item">
                                <Spelling :text="group.name" />
                            </li>
                            <template
                                v-for="pronoun in deduplicatePronounGroup(groupPronouns)"
                                :key="pronoun.canonicalName"
                            >
                                <li v-if="!pronoun.hidden" class="list-inline-item">
                                    <button
                                        :class="['btn', pronoun.name(glue) === selectedPronoun.name(glue) ? 'btn-primary' : 'btn-outline-primary', 'btn-sm', 'my-1']"
                                        @click="selectedPronoun = pronoun.clone(true)"
                                    >
                                        <Spelling :text="pronoun.name(glue)" />
                                    </button>
                                </li>
                            </template>
                        </ul>
                    </li>
                </template>
            </ul>
        </div>
        <div class="alert alert-primary">
            <p class="h3 mb-0 text-center">
                <Spelling escape :text="selectedPronoun.name(glue)" />
                <template v-if="config.pronouns.generator.description ?? true">
                    <br>
                    <input
                        v-model="selectedPronoun.description"
                        class="form-control form-input p-0 form-control-sm"
                        :size="selectedPronoun.description.length ? selectedPronoun.description.length + 3 : 16"
                        :maxlength="Pronoun.DESCRIPTION_MAXLENGTH"
                        :placeholder="$t('profile.description')"
                    >
                </template>
            </p>
        </div>
        <p>
            <T>pronouns.examples.header</T><T>quotation.colon</T>
        </p>
        <template
            v-for="{ examples: examplesOfHonorific, isHonorific } in examplesByHonorific"
            :key="isHonorific"
        >
            <ul>
                <li v-for="(example, i) in examplesOfHonorific" :key="i">
                    <template v-for="(part, j) in clearExampleParts(example.parts(selectedPronoun))" :key="j">
                        <input
                            v-if="part.variable"
                            v-model="selectedPronoun.morphemes[part.str]"
                            :class="['form-control form-input p-0', { active: selectedMorpheme === part.str }]"
                            :size="selectedPronoun.morphemes[part.str]?.length ?? 0"
                            maxlength="24"
                            @focus="selectedMorpheme = part.str"
                            @blur="selectedMorpheme = ''"
                        >
                        <span v-else><Spelling :text="part.str" /></span>
                    </template>
                </li>
            </ul>
            <div v-if="config.pronouns.plurals" class="my-3">
                <div v-if="isHonorific" class="custom-control custom-switch">
                    <input
                        id="pluralHonorific"
                        v-model="selectedPronoun.pluralHonorific[0]"
                        type="checkbox"
                        class="custom-control-input"
                    >
                    <label class="custom-control-label" for="pluralHonorific">
                        <T>pronouns.plural</T>
                        <Icon v="level-up" />
                    </label>
                </div>
                <div v-else class="custom-control custom-switch">
                    <input
                        id="plural"
                        v-model="selectedPronoun.plural[0]"
                        type="checkbox"
                        class="custom-control-input"
                    >
                    <label class="custom-control-label" for="plural">
                        <T>pronouns.plural</T>
                        <Icon v="level-up" />
                    </label>
                </div>
            </div>
        </template>
        <p class="small">
            <T icon="info-circle">home.generator.alt</T>
        </p>
        <!-- TODO #136
        <p class="small" v-if="config.pronunciation.enabled && $te('home.generator.pronunciation')">
            <Icon v="info-circle"/>
            <T>home.generator.pronunciation</T>
        </p>
        -->
    </PronounsGenerator>
</template>
