import { CHILD_STAY_RM_PER_NIGHT, ROOM_TYPES } from '../constants'

export function today() {
  return new Date().toISOString().slice(0, 10)
}

export function fmt(d) {
  return d ? new Date(d + 'T00:00:00').toLocaleDateString('en-MY', { day: '2-digit', month: 'short', year: 'numeric' }) : '-'
}

export function fmtMoney(n) {
  return 'RM ' + (n || 0).toFixed(2)
}

export function nights(ci, co) {
  return Math.max(1, Math.round((new Date(co) - new Date(ci)) / 86400000))
}

/** Adults + elderly for package DB lookup and package line (children billed via child stay fee only). */
export function packagePricingHeadcount(pax) {
  return Math.max(1, pax?.adult ?? 1) + Math.max(0, pax?.elderly ?? 0)
}

/** Children 0–2 (kidInfant) free; remaining children counted as 3–12 for nightly child rate. */
export function computeChildStayFee(pax, stayNights) {
  const n = Math.max(0, stayNights)
  const kid = Math.max(0, pax?.kid || 0)
  const kidInfant = Math.min(Math.max(0, pax?.kidInfant ?? 0), kid)
  const childrenCharged312 = Math.max(0, kid - kidInfant)
  return {
    childStayFee: childrenCharged312 * CHILD_STAY_RM_PER_NIGHT * n,
    childrenCharged312,
    kidInfant,
  }
}

export function genId(prefix) {
  return prefix + Date.now().toString().slice(-7)
}

export function isWeekend(d) {
  const day = new Date(d + 'T00:00:00').getDay()
  return day === 0 || day === 6
}

export function countFriSatNights(ci, co) {
  const checkin = new Date(`${ci}T00:00:00`)
  const checkout = new Date(`${co}T00:00:00`)
  if (Number.isNaN(checkin.getTime()) || Number.isNaN(checkout.getTime()) || checkout <= checkin) return 0

  let count = 0
  const cursor = new Date(checkin)
  while (cursor < checkout) {
    const day = cursor.getDay()
    if (day === 5 || day === 6) count += 1
    cursor.setDate(cursor.getDate() + 1)
  }
  return count
}

export function buildDefaultRooms() {
  const arr = []
  ROOM_TYPES.forEach((rt) => {
    for (let i = 1; i <= rt.units; i++) {
      arr.push({
        id: `${rt.code}-${String(i).padStart(2, '0')}`,
        type: rt.type,
        code: rt.code,
        maxPax: rt.maxPax,
        rate: rt.rate,
        status: 'available',
        currentBooking: null,
      })
    }
  })
  return arr
}

export function statusPill(s) {
  return { confirmed: 'pill-blue', 'checked-in': 'pill-teal', 'checked-out': 'pill-green', cancelled: 'pill-red' }[s] || 'pill-gray'
}

export function defaultTrips() {
  const d = today()
  return [
    { id: 'TR001', date: d, route: 'Mersing → Resort', time: '08:00', capacity: 20, booked: 12, rate: 30 },
    { id: 'TR002', date: d, route: 'Resort → Mersing', time: '14:00', capacity: 20, booked: 8, rate: 30 },
  ]
}

export function defaultEquipment() {
  return [
    { id: 'EQ001', name: 'BCD Jacket', cat: 'BCD', total: 10, available: 10, rate: 30 },
    { id: 'EQ002', name: 'Regulator Set', cat: 'Regulator', total: 10, available: 10, rate: 25 },
    { id: 'EQ003', name: 'Wetsuit 3mm', cat: 'Wetsuit', total: 12, available: 12, rate: 20 },
    { id: 'EQ004', name: 'Fins (pair)', cat: 'Fins', total: 15, available: 15, rate: 10 },
    { id: 'EQ005', name: 'Mask + Snorkel', cat: 'Mask', total: 20, available: 20, rate: 8 },
  ]
}

export function defaultInstructors() {
  return [
    { id: 'INS001', name: 'Ahmad Razak', role: 'Instructor', cert: 'PADI OWSI', dives: 18, commission: 50, status: 'Active' },
    { id: 'INS002', name: 'Lee Wei Keong', role: 'Dive Master', cert: 'PADI DM', dives: 32, commission: 30, status: 'Active' },
    { id: 'INS003', name: 'Maria Santos', role: 'Instructor', cert: 'SSI Level 1', dives: 12, commission: 50, status: 'Active' },
  ]
}

export function defaultAgents() {
  return [
    { id: 'AGT001', name: 'Discover Malaysia Tours', code: 'DISC10', type: 'percent', rate: 10, bookings: 5, earned: 1200, status: 'Active' },
    { id: 'AGT002', name: 'Island Hopper Agency', code: 'ISLE15', type: 'percent', rate: 15, bookings: 3, earned: 890, status: 'Active' },
  ]
}

export function initialBkData() {
  const tm = new Date()
  tm.setDate(tm.getDate() + 2)
  return {
    nationality: 'Malaysian',
    pax: { adult: 1, kid: 0, elderly: 0, kidInfant: 0 },
    splitPackages: false,
    packageAssignments: [],
    addons: [],
    agentCode: '',
    voucher: '',
    payMethod: 'cash',
    checkin: today(),
    checkout: tm.toISOString().slice(0, 10),
  }
}

export function computeFees(bkData, rooms) {
  const coDefault = () => {
    const t = new Date()
    t.setDate(t.getDate() + 2)
    return t.toISOString().slice(0, 10)
  }
  const checkinDate = bkData.checkin || today()
  const checkoutDate = bkData.checkout || coDefault()
  const n = nights(checkinDate, checkoutDate)
  const mixedPackageSubtotal = Number(bkData?.pricingMeta?.mixedPackageSubtotal || 0)
  const baseRate =
    bkData.roomRate ||
    ROOM_TYPES.find((r) => r.type === rooms.find((x) => x.id === bkData.room)?.type)?.rate?.weekday ||
    280
  const adultCount = bkData.pax?.adult || 1
  const friSatNights = countFriSatNights(checkinDate, checkoutDate)
  const weekendSurcharge = friSatNights * adultCount * 60
  const totalPax = (bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)
  const packagePricingPax = packagePricingHeadcount(bkData.pax)
  const { childStayFee, childrenCharged312, kidInfant } = computeChildStayFee(bkData.pax, n)
  const packageSubtotal =
    bkData.splitPackages && mixedPackageSubtotal > 0
      ? mixedPackageSubtotal
      : baseRate * packagePricingPax
  const boatFee = adultCount * 135
  const nationality = String(bkData?.nationality || '').trim().toLowerCase()
  const isMalaysian = nationality === 'malaysian'
  const tourismTax = isMalaysian ? 0 : totalPax * 10
  const gratuity = totalPax * 5
  return {
    weekendSurcharge,
    boatFee,
    tourismTax,
    gratuity,
    nights: n,
    baseRate,
    totalPax,
    packagePricingPax,
    packageSubtotal,
    childStayFee,
    childrenCharged312,
    kidInfant,
  }
}

export function calcBookingTotal(bkData) {
  const coDefault = () => {
    const t = new Date()
    t.setDate(t.getDate() + 2)
    return t.toISOString().slice(0, 10)
  }
  const n = bkData.fees?.nights || nights(bkData.checkin || today(), bkData.checkout || coDefault())
  const totalPax =
    bkData.fees?.totalPax ||
    (bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)
  const packagePricingPax = bkData.fees?.packagePricingPax ?? packagePricingHeadcount(bkData.pax)
  const baseRate = bkData.fees?.baseRate || bkData.roomRate || 280
  const base = bkData.fees?.packageSubtotal || baseRate * packagePricingPax
  const ws = bkData.fees?.weekendSurcharge || 0
  const boat = bkData.fees?.boatFee || 0
  const tt = bkData.fees?.tourismTax || 0
  const grat = bkData.fees?.gratuity || 0
  const addonsTotal = (bkData.addons || []).reduce((s, a) => s + a.price, 0)
  const childStayFee =
    bkData.fees?.childStayFee ??
    computeChildStayFee(bkData.pax, n).childStayFee
  const preTaxSub = base + ws + boat + tt + grat + addonsTotal + childStayFee
  const serviceCharge = preTaxSub * 0.1
  const sub = preTaxSub + serviceCharge
  const ag = bkData.agent
  const agentDisc = ag ? (ag.type === 'percent' ? sub * (ag.rate / 100) : ag.rate) : 0
  return {
    base,
    ws,
    boat,
    tt,
    grat,
    addonsTotal,
    childStayFee,
    serviceCharge,
    preTaxSub,
    sub,
    agentDisc,
    total: sub - agentDisc,
    n,
    totalPax,
    packagePricingPax,
    baseRate,
  }
}
