import { defineStore } from "pinia";
import { ref } from "vue";
import axios from "axios";
import { AxiosError } from "axios";
import {
    TArticle,
    TFilters,
    TPagination,
    TParams,
    TResponse,
} from "@/types/Article";

export const useArticleStore = defineStore("article", () => {
    // State
    const articles = ref<TArticle[]>([]);
    const filters = ref<TFilters>({
        page: 1,
        search: "",
        category: "",
    });
    const pagination = ref<TPagination>({
        total: 0,
        current_page: 1,
        last_page: 1,
        per_page: 6,
        first_page_url: null,
        next_page_url: null,
        prev_page_url: null,
        last_page_url: null,
    });
    const loading = ref<boolean>(false);
    const responseStatus = ref<number | null>(null);
    const lastSearchQuery = ref<string>("");

    // Actions
    const fetchArticles = async (
        pageParam: number = 1,
        searchParam: string,
        categoryParam: string
    ): Promise<void> => {
        loading.value = true;

        try {
            const finalSearch = searchParam
                ? searchParam
                : filters.value.search;
            const finalCategory = categoryParam
                ? categoryParam
                : filters.value.category;

            const params: Record<string, string | number> = {
                page: pageParam,
                search: finalSearch,
                category: finalCategory,
            };

            const response = await axios.get<TResponse>("/api/blog/search", {
                params,
            });

            if (response.status === 200) {
                articles.value = response.data.data?.data ?? [];
                pagination.value = {
                    total: response.data.data?.total ?? 0,
                    current_page: response.data.data?.current_page ?? 1,
                    last_page: response.data.data?.last_page ?? 1,
                    per_page: response.data.data?.per_page ?? 6,
                    first_page_url: response.data.data?.first_page_url ?? null,
                    next_page_url: response.data.data?.next_page_url ?? null,
                    prev_page_url: response.data.data?.prev_page_url ?? null,
                    last_page_url: response.data.data?.last_page_url ?? null,
                };
                responseStatus.value = response.status;
            } else {
                console.warn(
                    `API request failed with status: ${response.data.meta.code}`,
                    response.data
                );
                articles.value = [];
                pagination.value = {
                    total: 0,
                    current_page: 1,
                    last_page: 1,
                    per_page: 6,
                    first_page_url: null,
                    next_page_url: null,
                    prev_page_url: null,
                    last_page_url: null,
                };
                responseStatus.value = response.status;
            }
        } catch (error: AxiosError | unknown) {
            console.error("Error fetching articles:", error);
            articles.value = [];
            responseStatus.value = null;
            pagination.value = {
                total: 0,
                current_page: 1,
                last_page: 1,
                per_page: 6,
                first_page_url: null,
                next_page_url: null,
                prev_page_url: null,
                last_page_url: null,
            };
        } finally {
            loading.value = false;
        }
    };

    const setFilters = ({
        pageParam = 1,
        searchParam,
        categoryParam,
    }: TParams): void => {
        // Check if the current state matches the new parameters before updating
        const isStateMatching =
            articles.value.length > 0 &&
            pagination.value.current_page === pageParam &&
            lastSearchQuery.value === searchParam &&
            filters.value.category === categoryParam;

        // Only update state and fetch if the state doesn't match
        if (!isStateMatching) {
            filters.value.page = pageParam;
            filters.value.search = searchParam;
            filters.value.category = categoryParam;
            lastSearchQuery.value = searchParam;

            fetchArticles(pageParam, searchParam, categoryParam);
        }
    };

    const setPage = ({
        pageParam,
        searchParam = filters.value.search,
        categoryParam = filters.value.category,
    }: TParams): void => {
        setFilters({
            pageParam,
            searchParam,
            categoryParam,
        });
    };

    const clearFilters = (): void => {
        filters.value.page = 1;
        filters.value.search = "";
        filters.value.category = "";
        lastSearchQuery.value = "";

        fetchArticles(1, "", "");
    };

    return {
        articles,
        filters,
        pagination,
        loading,
        responseStatus,
        lastSearchQuery,
        fetchArticles,
        setFilters,
        setPage,
        clearFilters,
    };
});
