import { http } from '@inertiajs/vue3';
import type { QTableProps } from 'quasar';
import { reactive, ref } from 'vue';
import type { GridColumn, GridPagination } from '@/composables/useAdminGrid';
import { DEFAULT_GRID_SORT, normalizeGridSort } from '@/composables/useAdminGrid';
import type { CustomerIdentityVerification } from '@/constants/options';

export interface CustomerGridFilters {
    search: string | null;
    domain: string | null;
    status: {
        id: string;
        name: string;
    };
}

export interface CustomerGridRow {
    id: number;
    name: string;
    first_name: string | null;
    last_name: string | null;
    email: string;
    username: string | null;
    mobile_number: string | null;
    address: string | null;
    suburb: string | null;
    postcode: string | null;
    state: string | null;
    country: string | null;
    created_at: string | null;
    deleted_at: string | null;
    status: string;
    status_label: string;
    is_verified: boolean;
    no_charge: boolean;
    listings_count: number;
    online_auctions_count: number;
    in_person_auctions_count: number;
    is_in_person_official_user: boolean;
    domain: string;
    user_identity_verification: CustomerIdentityVerification | null;
    image: { path: string } | null;
    image_url: string | null;
}

export interface CustomerGridResponse {
    total: number;
    page: number;
    data: CustomerGridRow[];
}

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

function formatCustomerName(row: CustomerGridRow): string {
    return [row.first_name, row.last_name].filter(Boolean).join(' ');
}

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

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

    const filters = reactive<CustomerGridFilters>({
        search: (() => {
            if (typeof window === 'undefined') {
                return null;
            }

            const storedEmail = sessionStorage.getItem('customer_email');

            if (!storedEmail) {
                return null;
            }

            sessionStorage.removeItem('customer_email');

            return storedEmail;
        })(),
        domain: null,
        status: {
            id: 'active',
            name: 'Active',
        },
    });

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

    const columns: GridColumn[] = [
        { name: 'id', label: 'ID', align: 'left', field: 'id', sortable: true },
        { name: 'domain', align: 'left', label: 'Website', field: 'domain', sortable: true },
        { name: 'created_at', align: 'left', label: 'Date', field: 'created_at', sortable: true },
        {
            name: 'name',
            align: 'left',
            label: 'Name',
            field: (row) => formatCustomerName(row),
            sortable: true,
        },
        { name: 'username', align: 'left', label: 'Username', field: 'username', sortable: true },
        { name: 'items', align: 'left', label: 'Items', field: 'items', sortable: true },
        { name: 'email', align: 'left', label: 'Email', field: 'email', sortable: true },
        { name: 'mobile_number', align: 'left', label: 'Mobile number', field: 'mobile_number', sortable: true },
        { name: 'address', align: 'left', label: 'Address', field: 'address', sortable: true },
        {
            name: 'user_identity_verification',
            align: 'left',
            label: 'Document',
            field: 'user_identity_verification',
            sortable: true,
        },
        { name: 'status', align: 'left', label: 'Status', field: 'status', 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 CustomerGridResponse;

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

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

        const normalizedSort = normalizeGridSort(sortBy, descending);

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

        void fetchGrid();
    }

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

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