import { Router } from 'express';
import { z } from 'zod';
import { pool } from '../db/connection.js';
import { requireAuth } from '../middleware/auth.js';
import { requireIdempotencyKey } from '../middleware/idempotency.js';

const router = Router();

// Zod schema for offer creation validation
const createOfferSchema = z.object({
  amountChf: z.number().positive(),
  message: z.string().max(2000).optional()
});

// Zod schema for negotiation validation
const negotiateSchema = z.object({
  amountChf: z.number().positive(),
  message: z.string().max(2000).optional()
});

router.post('/:requestId', requireAuth, requireIdempotencyKey, async (req, res) => {
  try {
    const requestId = Number(req.params.requestId);
    if (Number.isNaN(requestId)) {
      return res.status(400).json({ error: 'Invalid requestId' });
    }

    const parsed = createOfferSchema.safeParse(req.body);

    if (!parsed.success) {
      return res.status(400).json({ error: 'Invalid payload', details: parsed.error.flatten() });
    }

    const { amountChf, message } = parsed.data;
    const [result] = await pool.query(
      `INSERT INTO offers (request_id, helper_id, amount_chf, message)
       VALUES (?, ?, ?, ?)`,
      [requestId, req.user.userId, amountChf, message || null]
    );

    await pool.query('UPDATE help_requests SET status = ? WHERE id = ?', ['negotiating', requestId]);

    // Cache the response for idempotent requests
    if (req.cacheIdempotentResponse) {
      await req.cacheIdempotentResponse(201, { id: result.insertId });
    }

    res.status(201).json({ id: result.insertId });
  } catch (error) {
    console.error('Error in POST /offers/:requestId:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.post('/negotiation/:offerId', requireAuth, requireIdempotencyKey, async (req, res) => {
  try {
    const offerId = Number(req.params.offerId);
    if (Number.isNaN(offerId)) {
      return res.status(400).json({ error: 'Invalid offerId' });
    }

    const parsed = negotiateSchema.safeParse(req.body);

    if (!parsed.success) {
      return res.status(400).json({ error: 'Invalid payload', details: parsed.error.flatten() });
    }

    const { amountChf, message } = parsed.data;
    const [result] = await pool.query(
      `INSERT INTO negotiations (offer_id, sender_id, amount_chf, message)
       VALUES (?, ?, ?, ?)`,
      [offerId, req.user.userId, amountChf, message || null]
    );

    await pool.query('UPDATE offers SET status = ? WHERE id = ?', ['countered', offerId]);

    // Cache the response for idempotent requests
    if (req.cacheIdempotentResponse) {
      await req.cacheIdempotentResponse(201, { id: result.insertId });
    }

    res.status(201).json({ id: result.insertId });
  } catch (error) {
    console.error('Error in POST /offers/negotiation/:offerId:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.post('/accept/:offerId', requireAuth, requireIdempotencyKey, async (req, res) => {
  try {
    const offerId = Number(req.params.offerId);
    if (Number.isNaN(offerId)) {
      return res.status(400).json({ error: 'Invalid offerId' });
    }

    const [offers] = await pool.query(
      'SELECT id, request_id, amount_chf FROM offers WHERE id = ? LIMIT 1',
      [offerId]
    );
    const offer = offers[0];
    if (!offer) {
      return res.status(404).json({ error: 'Offer not found' });
    }

    await pool.query('UPDATE offers SET status = ? WHERE id = ?', ['accepted', offerId]);
    await pool.query('UPDATE help_requests SET status = ? WHERE id = ?', ['agreed', offer.request_id]);

    const [dealResult] = await pool.query(
      'INSERT INTO deals (request_id, offer_id, agreed_amount_chf) VALUES (?, ?, ?)',
      [offer.request_id, offer.id, offer.amount_chf]
    );

    // Cache the response for idempotent requests
    if (req.cacheIdempotentResponse) {
      await req.cacheIdempotentResponse(201, { dealId: dealResult.insertId });
    }

    res.status(201).json({ dealId: dealResult.insertId });
  } catch (error) {
    console.error('Error in POST /offers/accept/:offerId:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

export default router;