<!-- List of articles view -->
<script setup lang="ts">
import { computed, inject, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import Axios from '~src/shared/axios';
import { AppConfigType, FiltersType, PostType } from '../types';
import Button from '../components/base/Button.vue';
import TextInput from '../components/form/TextInput.vue';
import ActiveFilters from '../components/filters/ActiveFilters.vue';
import Keywords from '../components/filters/Keywords.vue';
import Status from '../components/filters/Status.vue';
import Card from '../components/layout/Card.vue';
import Container from '../components/layout/Container.vue';
import PageHeading from '../components/layout/PageHeading.vue';
import Pagination from '../components/posts/Pagination.vue';
import PostsTable from '../components/posts/PostsTable.vue';
import { useNotificationStore } from '~src/admin/stores/useNotificationStore';
import useSetPageTitle from '../composables/useSetPageTitle';
import { useGettext } from 'vue3-gettext';

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

// Set page title
useSetPageTitle($gettext('List of articles'));

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

// Router
const router = useRouter();

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

// Filter component
const statusComponent = ref<InstanceType<typeof Status>>();
const keywordsComponent = ref<InstanceType<typeof Keywords>>();

// Active filters
const activeFilters = ref<FiltersType>({
    search: '',
    status: [],
    keywords: [],
});

// Status map
const statusMap = {
    'Scheduled to be generated': 'schedule_generate',
    'Scheduled for publication': 'schedule_publish',
    Published: 'published',
};

// Pagination
const currentPage = ref(1);
const pageSize = ref(12);
const totalPosts = ref(0);

// Loading
const loading = ref(false);

// Posts to be displayed
const posts = ref<PostType[]>([]);

// AbortController for cancelling requests
let abortController: AbortController | null = null;

// Get posts on mounted
onMounted(() => {
    fetchPosts();
});

// Change current page when page size changes
watch(pageSize, () => {
    currentPage.value = 1;
});

// Get posts when pagination or filters change
watch(
    [currentPage, pageSize, activeFilters],
    () => {
        fetchPosts();
    },
    {
        deep: true,
    }
);

// Get posts function
const fetchPosts = async () => {
    try {
        // Cancel the previous request if it exists
        if (abortController) {
            abortController.abort();
        }

        // Create a new AbortController instance
        abortController = new AbortController();

        // Set loading and reset posts
        posts.value = [];
        loading.value = true;

        // Construct the URL with query parameters
        const url = new URL(config.rest.endpoints.posts);
        const params = new URLSearchParams();

        // Add pagination parameters
        params.append('per_page', pageSize.value.toString());
        params.append('page', currentPage.value.toString());

        // Add the search parameter if it exists
        if (activeFilters.value.search) {
            params.append('search', activeFilters.value.search);
        }

        // Add the status parameter if it exists
        if (activeFilters.value.status?.length > 0) {
            params.append('status', activeFilters.value.status.map((status) => statusMap[status]).join(','));
        }

		 // Add the keywords parameter if it exists
		 if (activeFilters.value.keywords?.length > 0) {
            params.append('keywords', activeFilters.value.keywords.join(','));
        }

        // Append the query parameters to the URL
        url.search = params.toString();

        // Call the REST API
        const response = await Axios.get(url.toString(), { signal: abortController.signal });

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

        // Save the posts
        posts.value = response.data.data.posts;

        // Save pagination data
        currentPage.value = response.data.data.current_page;
        totalPosts.value = response.data.data.total_posts;

        loading.value = false;
    } catch (error) {
        // Handle error
        if (error.name !== 'CanceledError') {
            console.error($gettext('Error fetching posts:'), error);

            addNotification({
                message: $gettext('There was an error while fetching the posts!'),
                type: 'danger',
            });
            loading.value = false;
        }
    }
};

// Check if any filters are active
const filtersActive = computed(() => {
    return activeFilters.value.search || activeFilters.value.status.length || activeFilters.value.keywords.length;
});

// Account type
const isAccountFree = inject<boolean>('isAccountFree');
</script>

<template>
    <Container>
        <!-- Heading -->
        <PageHeading :heading="$gettext('List of articles')" />

        <!-- Filters -->
        <div class="flex items-center flex-col md:flex-row gap-3 md:gap-5 mt-7">
            <!-- Search -->
            <TextInput
                class="max-w-[300px]"
                :placeholder="$gettext('Search...')"
                v-model="activeFilters.search"
                :is-search="true"
            />

            <p>{{ $gettext('or filter by') }}</p>

            <div class="flex gap-3 md:gap-5 items-center">
                <!-- Status -->
                <Status
                    ref="statusComponent"
                    @update-active-status="(activeStatus : string[]) => activeFilters.status = activeStatus"
                />

                <!-- Keyword -->
                <Keywords
					ref="keywordsComponent"
                    @update-selected-keywords="(selectedKeywords : string[]) => activeFilters.keywords = selectedKeywords"
                />
            </div>
        </div>
        <!-- Filters -->

        <!-- Active filters -->
        <ActiveFilters
            :active-filters="activeFilters"
            @update-status="(status: string) => statusComponent.updateStatus(status)"
            @update-keywords="(keyword: string) => keywordsComponent.removeKeyword(keyword)"
            v-if="filtersActive"
        />

        <!-- Posts -->
        <PostsTable class="mt-5" :posts type="full" :loading @reload-posts="fetchPosts()" />

        <!-- Pagination -->
        <div class="flex justify-end mt-2.5">
            <Pagination :totalPosts v-model:current-page="currentPage" v-model:page-size="pageSize" />
        </div>

        <!-- Card -->
        <div class="max-w-[370px] mx-auto mt-[86px]" v-if="isAccountFree">
            <Card
                :image-url="`${config.plugin_url}/public/images/articles.png`"
                :image-alt="$gettext('Upgrade to premium plan')"
                type="vertical"
            >
                <div class="flex flex-col gap-6">
                    <p class="text-info-900">
                        {{ $gettext('On trial you can generate and publish only one article.') }}
                    </p>

                    <p class="text-info-900">
                        {{
                            $gettext(
                                'Upgrade to paid plan to publish articles more often - few times a day, on different hours.'
                            )
                        }}
                    </p>

                    <Button :text="$gettext('Upgrade')" size="large" @click.prevent="router.push('/upgrade')" />
                </div>
            </Card>
        </div>
    </Container>
</template>

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