import { Router } from 'express'
import { z } from 'zod'
import { prisma } from '../lib/prisma'
import { requireCompanyAuth } from '../middleware/requireCompanyAuth'
import { requireTenant } from '../middleware/requireTenant'
import { requireSubscription } from '../middleware/requireSubscription'

const router = Router()
router.use(requireCompanyAuth, requireTenant, requireSubscription)

const offerSchema = z.object({
  title:          z.string().min(1),
  description:    z.string().optional(),
  termsAndConds:  z.string().optional(),
  type:           z.enum(['PERCENTAGE','FIXED_AMOUNT','FREE_DAY','SPECIAL_RATE']),
  discountValue:  z.number().int().min(0),
  specialRate:    z.number().int().optional(),
  appliesToAll:   z.boolean().default(true),
  categories:     z.array(z.enum(['ECONOMY','COMPACT','MIDSIZE','FULLSIZE','SUV','LUXURY','VAN','TRUCK'])).default([]),
  minRentalDays:  z.number().int().optional(),
  maxRentalDays:  z.number().int().optional(),
  promoCode:      z.string().optional(),
  maxRedemptions: z.number().int().optional(),
  validFrom:      z.string().datetime(),
  validUntil:     z.string().datetime(),
  isActive:       z.boolean().default(true),
  isPublic:       z.boolean().default(true),
  isFeatured:     z.boolean().default(false),
  vehicleIds:     z.array(z.string()).default([]),
})

router.get('/', async (req, res, next) => {
  try {
    const { active, public: pub } = req.query as Record<string, string>
    const where: any = { companyId: req.companyId }
    if (active !== undefined) where.isActive = active === 'true'
    if (pub !== undefined)    where.isPublic = pub === 'true'
    const offers = await prisma.offer.findMany({ where, orderBy: { createdAt: 'desc' } })
    res.json({ data: offers })
  } catch (err) { next(err) }
})

router.post('/', async (req, res, next) => {
  try {
    const { vehicleIds, ...body } = offerSchema.parse(req.body)
    const offer = await prisma.offer.create({
      data: { ...body, companyId: req.companyId, validFrom: new Date(body.validFrom), validUntil: new Date(body.validUntil), vehicles: vehicleIds.length > 0 ? { create: vehicleIds.map((id) => ({ vehicleId: id })) } : undefined },
      include: { vehicles: true },
    })
    res.status(201).json({ data: offer })
  } catch (err) { next(err) }
})

router.get('/:id', async (req, res, next) => {
  try {
    const offer = await prisma.offer.findFirstOrThrow({ where: { id: req.params.id, companyId: req.companyId }, include: { vehicles: true } })
    res.json({ data: offer })
  } catch (err) { next(err) }
})

router.patch('/:id', async (req, res, next) => {
  try {
    const { vehicleIds, ...body } = offerSchema.partial().parse(req.body)
    const offer = await prisma.offer.updateMany({ where: { id: req.params.id, companyId: req.companyId }, data: { ...body, validFrom: body.validFrom ? new Date(body.validFrom) : undefined, validUntil: body.validUntil ? new Date(body.validUntil) : undefined } })
    if (offer.count === 0) return res.status(404).json({ error: 'not_found', message: 'Offer not found', statusCode: 404 })
    const updated = await prisma.offer.findUniqueOrThrow({ where: { id: req.params.id }, include: { vehicles: true } })
    res.json({ data: updated })
  } catch (err) { next(err) }
})

router.delete('/:id', async (req, res, next) => {
  try {
    await prisma.offer.deleteMany({ where: { id: req.params.id, companyId: req.companyId } })
    res.json({ data: { success: true } })
  } catch (err) { next(err) }
})

router.post('/:id/activate', async (req, res, next) => {
  try {
    await prisma.offer.updateMany({ where: { id: req.params.id, companyId: req.companyId }, data: { isActive: true } })
    res.json({ data: { success: true } })
  } catch (err) { next(err) }
})

router.post('/:id/deactivate', async (req, res, next) => {
  try {
    await prisma.offer.updateMany({ where: { id: req.params.id, companyId: req.companyId }, data: { isActive: false } })
    res.json({ data: { success: true } })
  } catch (err) { next(err) }
})

router.get('/:id/stats', async (req, res, next) => {
  try {
    const offer = await prisma.offer.findFirstOrThrow({ where: { id: req.params.id, companyId: req.companyId } })
    const reservations = await prisma.reservation.count({ where: { offerId: offer.id } })
    res.json({ data: { redemptions: offer.redemptionCount, reservations } })
  } catch (err) { next(err) }
})

export default router
