<!-- Shows table of posts -->
<script setup lang="ts">
import { AppConfigType, DropdownOptionType, PostType, PostStatusType } from '~src/admin/types';
import IconPlus from '../icons/IconPlus.vue';
import Badge from '../base/Badge.vue';
import IconQuestionCircle from '../icons/IconQuestionCircle.vue';
import Tooltip from '../base/Tooltip.vue';
import Checkboxes from '../form/Checkboxes.vue';
import Dropdown from '../navigation/Dropdown.vue';
import IconGear from '../icons/IconGear.vue';
import IconRefresh from '../icons/IconRefresh.vue';
import IconEye from '../icons/IconEye.vue';
import IconTrash from '../icons/IconTrash.vue';
import IconWarning from '../icons/IconWarning.vue';
import Message from '../base/Message.vue';
import Popup from '../layout/Popup.vue';
import { inject, ref, watch } from 'vue';
import { useNotificationStore } from '~src/admin/stores/useNotificationStore';
import Axios from '~src/shared/axios';
import Button from '../base/Button.vue';
import PopupTextarea from '../layout/PopupTextarea.vue';
import { useGettext } from 'vue3-gettext';
import PostKeywords from './PostKeywords.vue';
import { useTokensStore } from '~src/admin/stores/useTokensStore';

// Translations
const { $gettext } = useGettext();

// Get plugin config
const config: AppConfigType = inject('pluginConfig');

// Show notification
const { addNotification } = useNotificationStore();

// Control tokens
const { isTokenLimitReached, updateTokens } = useTokensStore();

// Props
const { posts, type, loading } = defineProps<{
    posts: PostType[];
    type: 'compact' | 'full';
    loading: boolean;
}>();

// Emits
const emit = defineEmits<{
    updatePosts: [posts: PostType[]];
    updateKeywords: [keywords: string[], dayIndex: number, timeIndex: number];
    reloadPosts: [];
}>();

// Loading
const requestLoading = ref(false);

// Dropdown options
const isAccountFree = inject<boolean>('isAccountFree');
const isAccountExpired = inject<boolean>('isAccountExpired');

const optionsDisabled = isAccountFree || isAccountExpired;
const dropdownOptions: DropdownOptionType[] = [
    {
        label: $gettext('Regenerate'),
        selected: false,
        icon: IconRefresh,
        disabled: optionsDisabled ? false : isTokenLimitReached.value,
    },
    {
        label: $gettext('Preview'),
        selected: false,
        icon: IconEye,
    },
    {
        label: isAccountFree ? $gettext('Delete (paid plan only)') : $gettext('Delete'),
        selected: false,
        icon: IconTrash,
        disabled: optionsDisabled,
    },
];

// Parse dropdown options for a specific post
const parseDropdownOptions = (dropdownOptions: DropdownOptionType[], status: PostStatusType) => {
    // If post has no content remove regenerate option
    if (status === 'schedule_generate' || status === 'published') {
        return dropdownOptions.map((option) => {
            if (option.label === $gettext('Regenerate')) {
                return { ...option, disabled: true };
            }
            return option;
        });
    }
    return dropdownOptions;
};

// Map for status
const statusMap = {
    published: {
        label: $gettext('Published'),
        type: 'success',
    },
    schedule_generate: {
        label: $gettext('Scheduled to be generated'),
        type: 'warning',
    },
    schedule_publish: {
        label: $gettext('Scheduled for publication'),
        type: 'info',
    },
};

// Popup control
const deletePopup = ref<InstanceType<typeof Popup>>();
const regeneratePopup = ref<InstanceType<typeof Popup>>();
const keywordPopup = ref<InstanceType<typeof PopupTextarea>>();

// Store keywords
const keywords = ref('');
const currentPostID = ref('');

// Save keywords
const saveKeywords = () => {
    // Keywords array
    let keywordsArr = keywords.value.split(/,|\r?\n/);

    // Make sure empty array is empty
    if (keywords.value.length === 0) {
        keywordsArr = [];
    }

    // Prepare new posts
    const newPosts = posts.map((p) => {
        if (p.id === currentPostID.value) {
            // Save to a article
            const newPost = p;
            newPost.keywords = keywordsArr;
            return newPost;
        }
        return p;
    });

    // Get weekday index
    const currentPost = posts.find((p) => p.id === currentPostID.value);
    const date = new Date(currentPost.publish_date);

    // Update the posts in the parent
    emit('updatePosts', newPosts);

    // Update the keywords in the schedule
    emit('updateKeywords', keywordsArr, date.getDay(), currentPost.timeIndex ?? null);

    // Close the popup
    keywordPopup.value.closePopup();
};

// Open keywords popup and set current id
const openKeywordsPopup = (id: string) => {
    currentPostID.value = id;
    const currentPost = posts.find((p) => p.id === id);

    // If current post has keywords, add them
    if (currentPost?.keywords) {
        keywords.value = currentPost.keywords.join(', ');
    }

    keywordPopup.value.openPopup();
};

// Single article actions
const selectedPost = ref<string | null>(null);

// Handle option click in dropdown
const handleOption = (option: string, index: number) => {
    // Set the article to perform action
    if (option.toLowerCase() === 'delete' || option.toLowerCase() === 'regenerate') {
        selectedPost.value = posts[index].id;
    }

    if (option.toLowerCase() === 'delete') {
        // Show delete popup
        deletePopup.value.openPopup();
    } else if (option.toLowerCase() === 'regenerate') {
        // Show regenerate popup
        regeneratePopup.value.openPopup();
    } else if (option.toLowerCase() === 'preview') {
        // Go to post edit page
        window.open(posts[index].post_link, '_blank');
    }
};

// Bulk actions checkboxes
const allPosts = ref<string[]>([]);
const selectedPosts = ref<string[]>([]);

// Select all posts
watch(allPosts, (newAllPosts) => {
    if (newAllPosts.includes('all_posts')) {
        // Select all
        selectedPosts.value = posts.map((p) => p.id.toString());
    } else {
        // Deselect all
        selectedPosts.value = [];
    }
});

// Bulk remove articles
const bulkRemoveArticles = () => {
    selectedPost.value = null;
    deletePopup.value.openPopup();
};

// Remove article
const removeArticle = async () => {
    try {
        // Start the call
        const body = prepareCall();

        // Call the WordPress Rest API to remove posts
        const response = await Axios.delete(config.rest.endpoints.posts, {
            data: body,
        });

        // Check if the response is successful
        if (response.status !== 200 || !response.data.success) {
            throw new Error(`REST API error: ${response.status} - ${response.statusText}`);
        }

        // Show all notificaitons
        showResponseMessages(
            response.data.post_success,
            response.data.post_errors,
            $gettext('Successfully deleted post'),
            $gettext("Couldn't delete post")
        );
    } catch (error) {
        console.error('Error during API call:', error);

        // Show error
        addNotification({
            message: $gettext('There was an error with deleting the posts!'),
            type: 'danger',
        });
    } finally {
        // Close popup
        deletePopup.value.closePopup();
        responseCleanup();
    }
};

// Bulk regenerate articles
const bulkRegenerateArticles = () => {
    selectedPost.value = null;
    regeneratePopup.value.openPopup();
};

// Regenerate article
const regenerateArticle = async () => {
    try {
        // Start the call
        const body = prepareCall();

        // Call the WordPress Rest API to regenerate posts
        const regenerateResponse = await Axios.post(`${config.rest.endpoints.posts}/regenerate`, body);

        // Check if the response is successful
        if (regenerateResponse.status !== 200 || !regenerateResponse.data.success) {
            throw new Error(`REST API error: ${regenerateResponse.status} - ${regenerateResponse.statusText}`);
        }

        // Show all notificaitons
        showResponseMessages(
            regenerateResponse.data.post_success,
            regenerateResponse.data.post_errors,
            $gettext('Successfully regenerated post'),
            $gettext("Couldn't regenerate post")
        );

        // Update tokens
        updateTokens();
    } catch (error) {
        console.error('Error during API call:', error);

        // Show error
        addNotification({
            message: $gettext('There was an error with regenerating the posts!'),
            type: 'danger',
        });
    } finally {
        // Close popup
        regeneratePopup.value.closePopup();
        responseCleanup();
    }
};

// Show API response messages
const showResponseMessages = (postSuccess: number[], postError: number[], successMsg: string, errorMsg: string) => {
    // Show success notificaitons
    postSuccess.forEach((postID: number) => {
        addNotification({
            message: `${successMsg} ${postID}!`,
            type: 'success',
        });
    });

    // Show error notificaitons
    postError.forEach((postID: number) => {
        addNotification({
            message: `${errorMsg} ${postID}!`,
            type: 'danger',
        });
    });
};

// Prepare API call
const prepareCall = () => {
    // Set loading
    requestLoading.value = true;

    // Prepare the body
    // If single article is selected use it instead perform action on all selected
    const body = {
        ids: selectedPost.value ? [selectedPost.value] : selectedPosts.value,
    };

    return body;
};

// After API call cleanup
const responseCleanup = () => {
    // Set loading
    requestLoading.value = false;

    // Reset selected posts
    if (selectedPost.value === null) {
        selectedPosts.value = [];
    } else {
        selectedPost.value = null;
    }

    // Reload posts
    emit('reloadPosts');
};
</script>

<template>
    <div class="mt-5">
        <!-- Bulk actions counter -->
        <div class="w-full flex justify-end items-center gap-4" v-if="selectedPosts.length">
            <!-- Regenerate -->
            <div
                class="flex gap-1.5 items-center cursor-pointer transition-colors hover:text-base-200"
                @click="bulkRegenerateArticles"
                @keypress.enter.space="bulkRegenerateArticles"
                tabindex="0"
            >
                <IconRefresh />
                <p>{{ $gettext('Regenerate') }} ({{ selectedPosts.length }} articles)</p>
            </div>

            <!-- Delete -->
            <div
                class="flex gap-1.5 items-center text-danger-500 cursor-pointer transition-colors hover:text-danger-300"
                @click="bulkRemoveArticles"
                @keypress.enter.space="bulkRegenerateArticles"
                tabindex="0"
            >
                <IconTrash />
                <p>{{ $gettext('Delete') }} ({{ selectedPosts.length }} articles)</p>
            </div>
        </div>

        <div class="overflow-x-auto lg:overflow-x-hidden mt-2">
            <table
                v-loading="loading"
                class="min-w-[750px] lg:min-w-[900px] max-w-full overflow-x-auto lg:overflow-x-hidden w-full border-separate border border-neutral-200 rounded-lg bg-white"
                v-if="loading || posts.length"
            >
                <!-- Table headings -->
                <thead>
                    <tr class="text-left text-base-200">
                        <!-- Checkbox -->
                        <th class="w-[35px] px-3 py-2.5 font-medium" v-if="type === 'full'">
                            <Checkboxes
                                :options="[{ label: '', value: 'all_posts' }]"
                                name="all_posts"
                                v-model="allPosts"
								:global-disabled="isAccountExpired"
                            />
                        </th>

                        <!-- Title -->
                        <th
                            :class="[
                                '2xl:w-full px-3 py-2.5 font-medium',
                                isAccountFree && 'w-[40%]',
                                !isAccountFree && 'w-[25%]',
                            ]"
                        >
                            {{ $gettext('Article') }}
                        </th>

                        <!-- Date -->
                        <th
                            :class="[
                                '2xl:min-w-[190px] px-3 py-2.5 font-medium',
                                isAccountFree && 'w-[25%]',
                                !isAccountFree && 'w-[15%]',
                            ]"
                        >
                            {{ $gettext('Date of publication') }}
                        </th>

                        <!-- Status -->
                        <th class="w-[20%] 2xl:min-w-[230px] px-3 py-2.5 font-medium" v-if="type === 'full'">
                            {{ $gettext('Status') }}
                        </th>

                        <!-- Keywords -->
                        <th
                            :class="[
                                'px-3 py-2.5 font-medium',
                                isAccountFree && 'w-[35%] 2xl:min-w-[220px]',
                                !isAccountFree && 'w-[25%] 2xl:min-w-[350px]',
                            ]"
                        >
                            <div class="flex items-center gap-2.5">
                                <span>{{ $gettext('Keywords') }}</span>

                                <Tooltip
                                    :content="
                                        $gettext(
                                            'Keywords match user queries, improve visibility, target specific audiences, guide content strategy, and enhance user experience, helping search engines index and rank your content effectively.'
                                        )
                                    "
                                    placement="top"
                                >
                                    <IconQuestionCircle />
                                </Tooltip>
                            </div>
                        </th>

                        <!-- Options -->
                        <th class="2xl:min-w-[110px] px-3 py-2.5 font-medium" v-if="type === 'full'"></th>
                    </tr>
                </thead>
                <!-- Table headings -->

                <!-- Table rows -->
                <tbody>
                    <!-- Loading row -->
                    <tr class="h-[200px]" v-if="loading"></tr>

                    <tr v-for="(post, i) in posts" :key="post.id">
                        <!-- Checkbox -->
                        <td class="w-[35px] border-t border-t-neutral-200 px-3 py-2.5" v-if="type === 'full'">
                            <Checkboxes
                                :options="[{ label: '', value: post.id.toString() }]"
                                name="posts"
                                v-model="selectedPosts"
								:global-disabled="isAccountExpired"
                            />
                        </td>

                        <!-- Title -->
                        <td
                            :class="[
                                '2xl:min-w-[unset] border-t border-t-neutral-200 px-3 py-2.5',
                                isAccountFree && 'w-[40%]',
                                !isAccountFree && 'w-[25%]',
                            ]"
                        >
                            {{ post.title }}
                        </td>

                        <!-- Date -->
                        <td
                            :class="[
                                '2xl:min-w-[190px] border-t border-t-neutral-200 px-3 py-2.5',
                                isAccountFree && 'w-[25%]',
                                !isAccountFree && 'w-[15%]',
                            ]"
                        >
                            {{ post.publish_date }}
                        </td>

                        <!-- Status -->
                        <td
                            class="w-[20%] 2xl:min-w-[230px] border-t border-t-neutral-200 px-3 py-2.5"
                            v-if="type === 'full'"
                        >
                            <Message
                                :message="statusMap[post.status].label"
                                :type="statusMap[post.status].type"
                                :show-icon="false"
                            />
                        </td>

                        <!-- Keywords -->
                        <td
                            :class="[
                                'border-t border-t-neutral-200 px-3 py-2.5',
                                isAccountFree && 'w-[35%] 2xl:min-w-[220px]',
                                !isAccountFree && 'w-[25%] 2xl:min-w-[350px]',
                            ]"
                        >
                            <!-- Compact type -->
                            <div class="flex items-center gap-1.5" v-if="type === 'compact'">
                                <div class="flex items-center" v-if="post.keywords.length === 0">
                                    <Button
                                        class="pl-0"
                                        :text="$gettext('Add keywords')"
                                        type="secondary"
                                        size="small"
                                        :has-background="false"
                                        :icon-position="'left'"
                                        :disabled="isAccountFree"
                                        @click.prevent="isAccountFree ? null : openKeywordsPopup(post.id)"
                                    >
                                        <IconPlus />
                                    </Button>
                                    <Badge type="warning" v-if="isAccountFree">{{ $gettext('PRO feature') }}</Badge>
                                </div>

                                <div
                                    class="flex gap-1.5 flex-wrap"
                                    @click="isAccountFree ? null : openKeywordsPopup(post.id)"
                                    v-else
                                >
                                    <Message
                                        v-for="(keyword, i) in post.keywords"
                                        :key="i"
                                        :message="keyword"
                                        type="neutral"
                                        :show-icon="false"
                                    />
                                </div>
                            </div>

                            <!-- Full type -->
                            <div v-else-if="type === 'full' && !isAccountFree">
                                <PostKeywords :keywords="post.keywords" />
                            </div>
                        </td>

                        <!-- Options -->
                        <td
                            class="2xl:min-w-[110px] border-t border-t-neutral-200 py-2.5 text-right"
                            v-if="type === 'full'"
                        >
                            <Dropdown
                                :options="parseDropdownOptions(dropdownOptions, post.status)"
                                placement="bottom-end"
                                @select-option="(option : string) => handleOption(option, i)"
                            >
                                <div>
                                    <IconGear class="mt-1 mx-3 group-aria-expanded:text-primary-500" />
                                </div>
                            </Dropdown>
                        </td>
                    </tr>
                </tbody>
                <!-- Table rows -->
            </table>

            <!-- No posts -->
            <div v-else-if="!posts.length">
                <p class="text-center text-lg font-bold mb-8">{{ $gettext('No posts to display!') }}</p>
            </div>
        </div>
    </div>

    <!-- Regenerate popup -->
    <Popup
        ref="regeneratePopup"
        :cancel-button-text="$gettext('Cancel')"
        :confirm-button-text="$gettext('Regenerate')"
        size="small"
        @popup-confirm="regenerateArticle"
        :loading="requestLoading"
    >
        <div class="text-center">
            <IconWarning class="mb-4 mx-auto" />
            <h2 class="text-[20px] leading-lg font-bold">{{ $gettext('Are you sure?') }}</h2>
            <p>{{ $gettext('Regenerating the article will use one of your weekly articles credits.') }}</p>
        </div>
    </Popup>

    <!-- Delete popup -->
    <Popup
        ref="deletePopup"
        :cancel-button-text="$gettext('Cancel')"
        :confirm-button-text="$gettext('Delete')"
        confirm-button-type="danger"
        size="small"
        @popup-confirm="removeArticle"
        :loading="requestLoading"
    >
        <div class="text-center">
            <IconWarning class="mb-4 mx-auto" />
            <h2 class="text-[20px] leading-lg font-bold">{{ $gettext('Are you sure?') }}</h2>
            <p>
                {{ $gettext('Deleting the article will remove it from articles list and from your website.') }}
                <br />
                {{ $gettext("You won't be able to restore it.") }}
            </p>
        </div>
    </Popup>

    <!-- Keywords popup -->
    <PopupTextarea
        ref="keywordPopup"
        :cancel-button-text="$gettext('Cancel')"
        :confirm-button-text="$gettext('Add keywords')"
        :heading="$gettext('Add keywords')"
        :placeholder="$gettext('Use comma or enter for separating keywords')"
        @popup-confirm="saveKeywords"
        v-model="keywords"
    />
</template>

<style lang="scss" scoped></style>
