export type ReservationCourtSelection = {
    court_id: number
    rate_id: number | string
}

export type ReservationRateOption = {
    id: number
    name: string
    price: number
}

export type ReservationTotalLine = {
    court_id: number
    rate_name: string
    hourly_price: number
    subtotal: number
}

export type ReservationTotals = {
    ready: boolean
    duration: number
    lines: ReservationTotalLine[]
    subtotal: number
    discount: number
    tax: number
    total: number
}

const roundMoney = (value: number) => Math.round((value + Number.EPSILON) * 100) / 100

const minutes = (time: string) => {
    const [hours = 0, mins = 0] = time.split(':').map(Number)
    return hours * 60 + mins
}

export const calculateReservationTotals = (input: {
    courts: ReservationCourtSelection[]
    rateOptions: Record<number, ReservationRateOption[]>
    startTime: string
    endTime: string
    discount: string | number
    applyTax: boolean
    taxRate: number
}): ReservationTotals => {
    const duration = input.startTime && input.endTime
        ? minutes(input.endTime) - minutes(input.startTime)
        : 0

    const lines = input.courts.flatMap(selection => {
        const rate = input.rateOptions[selection.court_id]
            ?.find(option => option.id === Number(selection.rate_id))

        if (!rate || duration <= 0) return []

        return [{
            court_id: selection.court_id,
            rate_name: rate.name,
            hourly_price: rate.price,
            subtotal: roundMoney((rate.price / 60) * duration),
        }]
    })

    const ready = input.courts.length > 0
        && duration > 0
        && lines.length === input.courts.length
    const subtotal = roundMoney(lines.reduce((sum, line) => sum + line.subtotal, 0))
    const requestedDiscount = Math.max(0, roundMoney(Number(input.discount) || 0))
    const discount = Math.min(requestedDiscount, subtotal)
    const tax = input.applyTax
        ? roundMoney((subtotal - discount) * (input.taxRate / 100))
        : 0

    return {
        ready,
        duration,
        lines,
        subtotal,
        discount,
        tax,
        total: roundMoney(subtotal - discount + tax),
    }
}
