import { BootstrapTableRequestDto } from "../dto/bootstrap-table-request.dto"

type FilterType =
    | 'string'
    | 'exact'
    | 'enum'
    | 'date'
    | 'dateRange'

export function buildWhereClause(
    query: BootstrapTableRequestDto,
    allowedFilters: Record<string, FilterType>,
    globalSearchColumns: string[],
) {
    const where: any = {}

    // =========================
    // Global Search
    // =========================
    if (query.search && globalSearchColumns.length > 0) {
        where.OR = globalSearchColumns.map((column) => {
            // ✅ Handle nested itemCode search
            if (column === 'items.itemCode') {
                return {
                    items: {
                        some: {
                            itemCode: {
                                contains: query.search,
                                mode: 'insensitive',
                            },
                        },
                    },
                }
            }
            // Default flat column search
            return {
                [column]: {
                    contains: query.search,
                    mode: 'insensitive',
                },
            }
        })
    }

    // =========================
    // Column Filters (Whitelist + Operators)
    // =========================
    if (query.filter) {
        Object.entries(query.filter).forEach(([key, value]) => {
            if (!allowedFilters[key]) return
            if (value === undefined || value === null || value === '') return

            const type = allowedFilters[key]

            // ✅ Handle _gte / _lte suffix
            if (key.endsWith('_gte') || key.endsWith('_lte')) {
                const [field, operator] = key.split('_')

                if (!where[field]) {
                    where[field] = {}
                }

                if (operator === 'gte') {
                    where[field].gte = new Date(value)
                }

                if (operator === 'lte') {
                    where[field].lte = new Date(value)
                }

                return
            }

            switch (type) {
                case 'string':
                    where[key] = {
                        contains: value,
                        mode: 'insensitive',
                    }
                    break

                case 'enum':
                    if (Array.isArray(value)) {
                        where[key] = { in: value }
                    } else {
                        where[key] = value  // fallback to single value
                    }
                    break

                case 'date':
                    where[key] = new Date(value)
                    break

                case 'exact':
                    where[key] = value
                    break

                case 'dateRange':
                    if (typeof value === 'object') {
                        const range: any = {}

                        // ✅ Support only GTE
                        if (value.gte) {
                            range.gte = new Date(value.gte)
                        }

                        // ✅ Support only LTE
                        if (value.lte) {
                            range.lte = new Date(value.lte)
                        }

                        // Only apply if at least one operator exists
                        if (Object.keys(range).length > 0) {
                            where[key] = range
                        }
                    }
                    break
            }
        })
    }

    return where
}