import {api} from "./client";
import {
    Event,
    GenericDataResponse,
    GenericPaginatedResponse,
    IdParam,
    Order,
    Organizer,
    OrganizerSettings,
    OrganizerStats,
    QueryFilters,
} from "../types";
import {queryParamsHelper} from "../utilites/queryParamsHelper.ts";
import {publicApi} from "./public-client.ts";

export const organizerClient = {
    create: async (organizer: Partial<Organizer>) => {
        const response = await api.post<GenericDataResponse<Organizer>>('organizers', organizer);
        return response.data;
    },

    all: async () => {
        const response = await api.get<GenericPaginatedResponse<Organizer>>('organizers');
        return response.data;
    },

    update: async (organizerId: IdParam, organizer: Partial<Organizer>) => {
        const response = await api.post<GenericDataResponse<Organizer>>('organizers/' + organizerId, organizer);
        return response.data;
    },

    findByID: async (organizerId: IdParam) => {
        const response = await api.get<GenericDataResponse<Organizer>>('organizers/' + organizerId);
        return response.data;
    },

    delete: async (organizerId: IdParam) => {
        const response = await api.delete('organizers/' + organizerId);
        return response.data;
    },

    getDeletionStatus: async (organizerId: IdParam) => {
        const response = await api.get<GenericDataResponse<{ can_delete: boolean; reason?: string }>>('organizers/' + organizerId + '/deletion-status');
        return response.data;
    },

    updateStatus: async (organizerId: IdParam, status: string) => {
        const response = await api.put<GenericDataResponse<Organizer>>('organizers/' + organizerId + '/status', {
            status
        });
        return response.data;
    },

    findEventsByOrganizerId: async (organizerId: IdParam, pagination: QueryFilters) => {
        const response = await api.get<GenericPaginatedResponse<Event>>(
            'organizers/' + organizerId + '/events' + queryParamsHelper.buildQueryString(pagination)
        );
        return response.data;
    },

    getOrganizerStats: async (organizerId: IdParam, currencyCode: string) => {
        const response = await api.get<GenericDataResponse<OrganizerStats>>('organizers/' + organizerId + '/stats?currency_code=' + currencyCode);
        return response.data;
    },

    getOrganizerOrders: async (organizerId: IdParam, pagination: QueryFilters) => {
        const response = await api.get<GenericPaginatedResponse<Order>>(
            `organizers/${organizerId}/orders` + queryParamsHelper.buildQueryString(pagination),
        );
        return response.data;
    },

    getOrganizerReport: async (
        organizerId: IdParam,
        reportType: string,
        startDate?: string | null,
        endDate?: string | null,
        currency?: string | null,
        eventId?: IdParam | null,
        page?: number,
        perPage?: number
    ) => {
        const params = new URLSearchParams();
        if (startDate) params.append('start_date', startDate);
        if (endDate) params.append('end_date', endDate);
        if (currency) params.append('currency', currency);
        if (eventId) params.append('event_id', String(eventId));
        if (page) params.append('page', String(page));
        if (perPage) params.append('per_page', String(perPage));

        const queryString = params.toString() ? `?${params.toString()}` : '';
        const response = await api.get<{
            data: any[];
            pagination?: {
                total: number;
                page: number;
                per_page: number;
                last_page: number;
            };
        }>(
            `organizers/${organizerId}/reports/${reportType}${queryString}`
        );
        return response.data;
    },

    exportOrganizerReport: async (
        organizerId: IdParam,
        reportType: string,
        startDate?: string | null,
        endDate?: string | null,
        currency?: string | null,
        eventId?: IdParam | null
    ): Promise<Blob> => {
        const params = new URLSearchParams();
        if (startDate) params.append('start_date', startDate);
        if (endDate) params.append('end_date', endDate);
        if (currency) params.append('currency', currency);
        if (eventId) params.append('event_id', String(eventId));

        const queryString = params.toString() ? `?${params.toString()}` : '';
        const response = await api.get(
            `organizers/${organizerId}/reports/${reportType}/export${queryString}`,
            { responseType: 'blob' }
        );

        return new Blob([response.data]);
    },
}

export const organizerPublicClient = {
    findByID: async (organizerId: IdParam) => {
        const response = await publicApi.get<GenericDataResponse<Organizer>>('organizers/' + organizerId);
        return response.data;
    },

    findEventsByOrganizerId: async (organizerId: IdParam, pagination: QueryFilters) => {
        const response = await publicApi.get<GenericPaginatedResponse<Event>>(
            'organizers/' + organizerId + '/events' + queryParamsHelper.buildQueryString(pagination)
        );
        return response.data;
    },

    getEvents: async (organizerId: IdParam, pagination: QueryFilters) => {
        const response = await publicApi.get<GenericPaginatedResponse<Event>>(
            'organizers/' + organizerId + '/events' + queryParamsHelper.buildQueryString(pagination)
        );
        return response.data;
    },

    contactOrganizer: async (organizerId: IdParam, contactData: {
        name: string;
        email: string;
        message: string;
    }) => {
        const response = await publicApi.post<GenericDataResponse<any>>(
            `organizers/${organizerId}/contact`, 
            contactData
        );
        return response.data;
    },
}

export const organizerSettingsClient = {
    partialUpdate: async (organizerId: IdParam, settings: Partial<OrganizerSettings>) => {
        const response = await api.patch<GenericDataResponse<OrganizerSettings>>('organizers/' + organizerId + '/settings', settings);
        return response.data;
    },

    all: async (organizerId: IdParam) => {
        const response = await api.get<GenericDataResponse<OrganizerSettings>>('organizers/' + organizerId + '/settings');
        return response.data;
    },
}
