import { http } from '@inertiajs/vue3';
import type { QTableProps } from 'quasar';
import { reactive, ref } from 'vue';
import type { GridColumn, GridFilters, GridPagination } from '@/composables/useAdminGrid';

export interface PlanGridRow {
    id: number;
    plan_type: string;
    name: string;
    cost: string;
    is_popular: boolean;
    no_of_days: number;
    deleted_at: string | null;
}

export interface PlanGridResponse {
    total: number;
    page: number;
    data: PlanGridRow[];
}

type TableRequest = Parameters<NonNullable<QTableProps['onRequest']>>[0];

function buildGridPayload(
    pagination: GridPagination,
    filters: GridFilters,
): GridPagination & { filters: GridFilters } {
    return {
        page: pagination.page,
        rowsPerPage: pagination.rowsPerPage,
        sortBy: pagination.sortBy,
        descending: pagination.descending,
        rowsNumber: pagination.rowsNumber,
        filters: {
            search: filters.search,
            status: { ...filters.status },
        },
    };
}

export function usePlanGrid(gridUrl: string, initialGrid?: PlanGridResponse) {
    const loading = ref(false);
    const rows = ref<PlanGridRow[]>(initialGrid?.data ?? []);

    const filters = reactive<GridFilters>({
        search: null,
        status: {
            id: 'active',
            name: 'Active',
        },
    });

    const pagination = ref<GridPagination>({
        sortBy: 'id',
        descending: false,
        page: initialGrid?.page ?? 1,
        rowsPerPage: 10,
        rowsNumber: initialGrid?.total ?? 0,
    });

    const columns: GridColumn[] = [
        { name: 'id', label: 'ID', align: 'left', field: 'id', sortable: true },
        { name: 'plan_type', align: 'left', label: 'Plan Type', field: 'plan_type', sortable: true },
        { name: 'name', align: 'left', label: 'Name', field: 'name', sortable: true },
        { name: 'cost', align: 'right', label: 'Cost', field: 'cost', sortable: true },
        { name: 'is_popular', align: 'left', label: 'Is Popular', field: 'is_popular', sortable: true },
        { name: 'no_of_days', align: 'right', label: 'No. of Days', field: 'no_of_days', sortable: true },
        { name: 'actions', align: 'left', label: 'Actions', field: 'id' },
    ];

    async function fetchGrid(): Promise<void> {
        loading.value = true;

        const payload = buildGridPayload(pagination.value, filters);

        try {
            const response = await http.getClient().request({
                method: 'post',
                url: gridUrl,
                data: JSON.stringify(payload),
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                },
            });

            const result = JSON.parse(response.data) as PlanGridResponse;

            rows.value = result.data;
            pagination.value.rowsNumber = result.total;
            pagination.value.page = result.page;
        } catch (error) {
            console.error('Failed to load grid data', error);
        } finally {
            loading.value = false;
        }
    }

    function applyRequestPagination(requestProps: TableRequest): void {
        const { page, rowsPerPage, sortBy, descending } = requestProps.pagination;
        const rowsNumber = pagination.value.rowsNumber;

        pagination.value.page = page;
        pagination.value.rowsPerPage = rowsPerPage;
        pagination.value.sortBy = sortBy;
        pagination.value.descending = descending;
        pagination.value.rowsNumber = rowsNumber;
    }

    function onRequest(requestProps: TableRequest): void {
        applyRequestPagination(requestProps);
        void fetchGrid();
    }

    function onFilterChange(): void {
        pagination.value.page = 1;
        void fetchGrid();
    }

    return {
        loading,
        rows,
        filters,
        pagination,
        columns,
        fetchGrid,
        onRequest,
        onFilterChange,
    };
}
