<script setup lang="ts">
import { computed, ref } from 'vue';
import { StyleService } from '@/Stores/style.service';
import { mdiTrashCan } from '@mdi/js';
import BaseLevel from '@/Components/BaseLevel.vue';
import BaseButtons from '@/Components/BaseButtons.vue';
import BaseButton from '@/Components/BaseButton.vue';
import { Subject } from '@/Dataset';
import FormControl from '@/Components/FormControl.vue';
import SearchCategoryAutocomplete from '@/Components/SearchCategoryAutocomplete.vue';
import { mdiRefresh } from '@mdi/js';

const props = defineProps({
    checkable: Boolean,
    keywords: {
        type: Array<Subject>,
        default: () => [],
    },
    subjectTypes: {
        type: Object,
        default: () => ({}),
    },
    errors: {
        type: Object,
        default: () => ({}),
    },
    subjectsToDelete: {
        type: Array<Subject>,
        default: [],
    }
});

const emit = defineEmits(['update:subjectsToDelete']);

// Create a computed property for subjectsToDelete with getter and setter
const deletetSubjects = computed({
    get: () => props.subjectsToDelete,
    set: (values: Array<Subject>) => {
        props.subjectsToDelete.length = 0;
        props.subjectsToDelete.push(...values);
        emit('update:subjectsToDelete', values);
    }
});

const styleService = StyleService();
const items = computed(() => props.keywords);

const perPage = ref(5);
const currentPage = ref(0);

const itemsPaginated = computed(() => {
    return items.value.slice(perPage.value * currentPage.value, perPage.value * (currentPage.value + 1));
});

const numPages = computed(() => Math.ceil(items.value.length / perPage.value));

const currentPageHuman = computed(() => currentPage.value + 1);

const pagesList = computed(() => {
    const pagesList: Array<number> = [];

    for (let i = 0; i < numPages.value; i++) {
        pagesList.push(i);
    }

    return pagesList;
});

const removeItem = (key: number) => {
    const item = items.value[key];

    // If the item has an ID, add it to the delete list
    if (item.id) {
        addToDeleteList(item);
    }

    // Remove from the visible list
    items.value.splice(key, 1);
};

// Helper function to add a subject to the delete list
const addToDeleteList = (subject: Subject) => {
    if (subject.id) {
        const newList = [...props.subjectsToDelete, subject];
        deletetSubjects.value = newList;
    }
};

// Helper function to reactivate a subject (remove from delete list)
const reactivateSubject = (index: number) => {
    const newList = [...props.subjectsToDelete];
    const removedSubject = newList.splice(index, 1)[0];
    deletetSubjects.value = newList;

    // Add the subject back to the keywords list if it's not already there
    if (removedSubject && !props.keywords.some(k => k.id === removedSubject.id)) {
        props.keywords.push(removedSubject);
    }
};

const isKeywordReadOnly = (item: Subject) => {
    return (item.dataset_count ?? 0) > 1 || item.type !== 'uncontrolled';
};

const formatError = (error: string | string[] | undefined | null): string => {
    if (!error) return '';
    return Array.isArray(error) ? error.join(', ') : error;
};
</script>

<template>

    <table>
        <thead>
            <tr>
                <th scope="col">Type</th>
                <th scope="col" class="relative">
                    Value
                    <div class="inline-block relative ml-1 group">
                        <button
                            class="w-4 h-4 rounded-full bg-gray-200 text-gray-600 text-xs flex items-center justify-center focus:outline-none hover:bg-gray-300">
                            i
                        </button>
                        <div
                            class="absolute left-0 top-full mt-1 w-64 bg-white shadow-lg rounded-md p-3 text-xs text-left z-50 transform scale-0 origin-top-left transition-transform duration-100 group-hover:scale-100">
                            <p class="text-gray-700">
                                Keywords are only editable if they are used by a single dataset (Usage Count = 1)".
                            </p>
                            <div class="absolute -top-1 left-1 w-2 h-2 bg-white transform rotate-45"></div>
                        </div>
                    </div>
                </th>
                <th scope="col">Language</th>
                <th scope="col">Usage Count</th>
                <th scope="col" />
            </tr>
        </thead>
        <tbody>
            <tr v-for="(item, index) in itemsPaginated" :key="item.id ?? index">

                <td data-label="Type" scope="row">
                    <FormControl required v-model="item.type"
                        @update:modelValue="() => { item.value = ''; }" :type="'select'"
                        placeholder="[Enter Language]" :options="props.subjectTypes">
                        <div class="text-red-400 text-sm" v-if="errors[`subjects.${index}.type`]">
                            {{ formatError(errors[`subjects.${index}.type`]) }}
                        </div>
                    </FormControl>
                </td>

                <td data-label="Value" scope="row">
                    <SearchCategoryAutocomplete v-if="item.type !== 'uncontrolled'" v-model="item.value" @subject="
                        (result) => {
                            item.language = result.language;
                            item.external_key = result.uri;
                        }
                    " :is-read-only="item.dataset_count > 1">
                        <div class="text-red-400 text-sm" v-if="errors[`subjects.${index}.value`]">
                            {{ formatError(errors[`subjects.${index}.value`]) }}
                        </div>
                    </SearchCategoryAutocomplete>

                    <FormControl v-else required v-model="item.value" type="text" placeholder="[enter keyword value]"
                        :borderless="true" :is-read-only="item.dataset_count > 1">
                        <div class="text-red-400 text-sm" v-if="errors[`subjects.${index}.value`]">
                            {{ formatError(errors[`subjects.${index}.value`]) }}
                        </div>
                    </FormControl>
                </td>

                <td data-label="Language" scope="row">
                    <FormControl required v-model="item.language" :type="'select'" placeholder="[Enter Lang]"
                        :options="{ de: 'de', en: 'en' }" :is-read-only="isKeywordReadOnly(item)">
                        <div class="text-red-400 text-sm" v-if="errors[`subjects.${index}.language`]">
                            {{ formatError(errors[`subjects.${index}.language`]) }}
                        </div>
                    </FormControl>
                </td>

                <td data-label="Usage Count" scope="row">
                    <div class="text-center">
                        {{ item.dataset_count || 1 }}
                    </div>
                </td>

                <td class="before:hidden lg:w-1 whitespace-nowrap" scope="row">
                    <BaseButtons type="justify-start lg:justify-end" no-wrap>
                        <BaseButton color="danger" :icon="mdiTrashCan" small @click.prevent="removeItem(index)" />
                    </BaseButtons>
                </td>
            </tr>
        </tbody>
    </table>

    <div class="p-3 lg:px-6 border-t border-gray-100 dark:border-slate-800">
        <BaseLevel>
            <BaseButtons>
                <BaseButton v-for="page in pagesList" :key="page" :active="page === currentPage" :label="page + 1" small
                    :outline="styleService.darkMode" @click="currentPage = page" />
            </BaseButtons>
            <small>Page {{ currentPageHuman }} of {{ numPages }}</small>
        </BaseLevel>
    </div>

    <!-- Aggregate error for the whole subjects collection, e.g. "at least 3 keywords must be defined" -->
    <div class="text-red-400 text-sm" v-if="errors.subjects">
        {{ formatError(errors.subjects) }}
    </div>

    <!-- Subjects to delete section -->
    <div v-if="deletetSubjects.length > 0" class="mt-8">
        <h1 class="pt-8 pb-3 font-semibold sm:text-lg text-gray-900">Keywords To Delete</h1>
        <ul id="deleteSubjects" tag="ul" class="flex flex-1 flex-wrap -m-1">
            <li v-for="(element, index) in deletetSubjects" :key="index"
                class="block p-1 w-1/2 sm:w-1/3 md:w-1/4 lg:w-1/6 xl:w-1/8 h-32">
                <article tabindex="0"
                    class="bg-red-100 group w-full h-full rounded-md cursor-pointer relative shadow-sm overflow-hidden">
                    <section
                        class="flex flex-col rounded-md text-xs break-words w-full h-full z-20 absolute top-0 py-2 px-3">
                        <h1 class="flex-1 text-gray-700 group-hover:text-blue-800 font-medium text-sm mb-1">{{
                            element.value }}</h1>
                        <div class="flex items-center justify-between mt-auto">
                            <div class="flex flex-col">
                                <p class="p-1 size text-xs text-gray-700">
                                    <span class="font-semibold">Type:</span> {{ element.type }}
                                </p>
                                <p class="p-1 size text-xs text-gray-700" v-if="element.dataset_count">
                                    <span class="font-semibold">Used by:</span>
                                    <span
                                        class="inline-flex items-center justify-center bg-gray-200 text-gray-800 rounded-full w-5 h-5 text-xs">
                                        {{ element.dataset_count }}
                                    </span> datasets
                                </p>
                            </div>
                            <button
                                class="delete ml-auto focus:outline-none hover:bg-gray-300 p-1 rounded-md text-gray-800"
                                @click.prevent="reactivateSubject(index)">
                                <svg viewBox="0 0 24 24" class="w-5 h-5">
                                    <path fill="currentColor" :d="mdiRefresh"></path>
                                </svg>
                            </button>
                        </div>
                    </section>
                </article>
            </li>
        </ul>
    </div>


</template>

<style scoped>
/* tr:nth-child(even) {
    background: gray;
}

tr:nth-child(od) {
    background: white;
} */
</style>