import { defineStore } from 'pinia';
import { ApiJobRepository } from '../../infrastructure/api/ApiJobRepository';

const jobRepository = new ApiJobRepository();

const ACTIVE_STATUSES = ['pending', 'in_progress'];

export const useActivityStore = defineStore('activity', {
    state: () => ({
        jobs: [],
        loading: false,
        error: null,
        mercureEventSource: null,
        // Pagination
        currentPage: 1,
        totalPages: 0,
        total: 0,
        limit: 20,
        hasNextPage: false,
        hasPreviousPage: false,
        // Tri
        sortBy: 'createdAt',
        sortOrder: 'DESC',
    }),

    getters: {
        activeJobs: state => state.jobs.filter(job => job.isActive()),
        isLoading: state => state.loading,
        hasError: state => !!state.error,
        paginationInfo: state => ({
            currentPage: state.currentPage,
            totalPages: state.totalPages,
            total: state.total,
            limit: state.limit,
            hasNextPage: state.hasNextPage,
            hasPreviousPage: state.hasPreviousPage
        })
    },

    actions: {
        async loadJobs(page = null) {
            this.loading = true;
            this.error = null;

            try {
                const jobCollection = await jobRepository.getJobs({
                    page: page || this.currentPage,
                    limit: this.limit,
                    sortBy: this.sortBy,
                    sortOrder: this.sortOrder,
                    status: ACTIVE_STATUSES,
                });

                this.jobs = jobCollection.items;
                this.currentPage = jobCollection.page;
                this.total = jobCollection.total;
                this.hasNextPage = jobCollection.hasNextPage;
                this.hasPreviousPage = jobCollection.hasPreviousPage;
                this.totalPages = Math.ceil(this.total / this.limit);
            } catch (error) {
                this.error = error.message;
                console.error('Error loading jobs:', error);
            } finally {
                this.loading = false;
            }
        },

        async goToPage(page) {
            if (page >= 1 && page <= this.totalPages && page !== this.currentPage) {
                this.currentPage = page;
                await this.loadJobs(page);
            }
        },

        async updateSort(sortBy, sortOrder) {
            this.sortBy = sortBy;
            this.sortOrder = sortOrder;
            this.currentPage = 1;
            await this.loadJobs(1);
        },

        async updateLimit(limit) {
            this.limit = limit;
            this.currentPage = 1;
            await this.loadJobs(1);
        },

        async deleteJob(id) {
            this.loading = true;
            this.error = null;

            try {
                await jobRepository.deleteJob(id);
                this.jobs = this.jobs.filter(job => job.id !== id);
                await this.loadJobs(this.currentPage);
            } catch (error) {
                this.error = error.message;
                console.error('Error deleting job:', error);
            } finally {
                this.loading = false;
            }
        },

        updateJobProgress(jobId, progress) {
            const job = this.jobs.find(j => j.id === jobId);
            if (job) job.progress = progress;
        },

        subscribeMercure() {
            if (this.mercureEventSource) return;
            const url = new URL('/.well-known/mercure', window.location.origin);
            url.searchParams.append('topic', 'jobs/activity');
            this.mercureEventSource = new EventSource(url.toString());
            this.mercureEventSource.onmessage = (event) => {
                const data = JSON.parse(event.data);
                if (data.type === 'job.progress_updated') {
                    this.updateJobProgress(data.jobId, data.progress);
                }
            };
        },

        unsubscribeMercure() {
            if (this.mercureEventSource) {
                this.mercureEventSource.close();
                this.mercureEventSource = null;
            }
        },

        async deleteJobs(criteria = {}) {
            this.loading = true;
            this.error = null;

            try {
                const deleted = await jobRepository.deleteJobs(criteria);
                await this.loadJobs(this.currentPage);
                return deleted;
            } catch (error) {
                this.error = error.message;
                console.error('Error deleting jobs:', error);
            } finally {
                this.loading = false;
            }
        },
    }
});
