import { Router } from 'express'
import { requireCompanyAuth } from '../../middleware/requireCompanyAuth'
import { requireTenant } from '../../middleware/requireTenant'
import { requireSubscription } from '../../middleware/requireSubscription'
import { requireRole } from '../../middleware/requireRole'
import { parseBody, parseParams } from '../../http/validate'
import { ok } from '../../http/respond'
import { getRawBodyString, parseRawJsonBody } from '../../http/webhooks'
import * as amanpay from '../../services/amanpayService'
import * as paypal from '../../services/paypalService'
import * as service from './payment.service'
import { chargeSchema, manualPaymentSchema, refundSchema, capturePaypalSchema, reservationParamSchema, paymentParamSchema } from './payment.schemas'

const router = Router()

// ─── Webhooks (no auth) ────────────────────────────────────────

router.post('/webhooks/amanpay', async (req, res, next) => {
  try {
    const rawBody   = getRawBodyString(req)
    const payload   = parseRawJsonBody(req)
    const signature = (req.headers['x-amanpay-signature'] as string) ?? ''
    if (!amanpay.isConfigured() || !amanpay.verifyWebhookSignature(rawBody, signature)) {
      return res.status(401).json({ error: 'invalid_signature' })
    }
    await service.handleAmanpayWebhook(payload, rawBody)
    res.json({ received: true })
  } catch (err) { next(err) }
})

router.post('/webhooks/paypal', async (req, res, next) => {
  try {
    const rawBody = getRawBodyString(req)
    const payload = parseRawJsonBody(req)
    const isValid = await paypal.verifyWebhookEvent(req.headers as Record<string, string>, rawBody)
    if (!paypal.isConfigured() || !isValid) return res.status(401).json({ error: 'invalid_signature' })
    await service.handlePaypalWebhook(payload, rawBody)
    res.json({ received: true })
  } catch (err) { next(err) }
})

// ─── Authenticated ────────────────────────────────────────────

router.use(requireCompanyAuth, requireTenant, requireSubscription)

router.get('/company', async (req, res, next) => {
  try {
    ok(res, await service.listByCompany(req.companyId))
  } catch (err) { next(err) }
})

router.get('/reservations/:id', async (req, res, next) => {
  try {
    const { id } = parseParams(reservationParamSchema, req)
    ok(res, await service.listByReservation(id, req.companyId))
  } catch (err) { next(err) }
})

router.post('/reservations/:id/charge', requireRole('MANAGER'), async (req, res, next) => {
  try {
    const { id }   = parseParams(reservationParamSchema, req)
    const body     = parseBody(chargeSchema, req)
    ok(res, await service.initCharge(id, req.companyId, body))
  } catch (err) { next(err) }
})

router.post('/reservations/:id/capture-paypal', requireRole('MANAGER'), async (req, res, next) => {
  try {
    const { id }          = parseParams(reservationParamSchema, req)
    const { paypalOrderId } = parseBody(capturePaypalSchema, req)
    ok(res, await service.capturePaypal(id, req.companyId, paypalOrderId))
  } catch (err) { next(err) }
})

router.post('/reservations/:id/manual', requireRole('OWNER'), async (req, res, next) => {
  try {
    const { id } = parseParams(reservationParamSchema, req)
    const body   = parseBody(manualPaymentSchema, req)
    ok(res, await service.recordManualPayment(id, req.companyId, body))
  } catch (err) { next(err) }
})

router.post('/reservations/:reservationId/payments/:paymentId/refund', requireRole('MANAGER'), async (req, res, next) => {
  try {
    const { reservationId, paymentId } = parseParams(paymentParamSchema, req)
    const { amount, reason }           = parseBody(refundSchema, req)
    ok(res, await service.refundPayment(reservationId, paymentId, req.companyId, amount, reason))
  } catch (err) { next(err) }
})

export default router
