import { Router } from 'express';
import { z } from 'zod';
import { pool } from '../db/connection.js';
import { requireAuth } from '../middleware/auth.js';
import { createError, sendError } from '../utils/errorHandler.js';

const router = Router();

const getDealParticipants = async (dealId) => {
  try {
    const [rows] = await pool.query(
      `SELECT d.id, hr.requester_id, o.helper_id
       FROM deals d
       JOIN help_requests hr ON hr.id = d.request_id
       JOIN offers o ON o.id = d.offer_id
       WHERE d.id = ? LIMIT 1`,
      [dealId]
    );

    return rows[0] || null;
  } catch (error) {
    console.error('Database error while fetching deal participants for dealId:', dealId, error);
    throw createError('DATABASE_ERROR', 'Database error while fetching deal participants');
  }
};

router.post('/request', requireAuth, async (req, res) => {
  try {
    const parsed = z.object({ 
      dealId: z.number().int().positive(), 
      targetUserId: z.number().int().positive() 
    }).safeParse(req.body);
    
    if (!parsed.success) {
      throw createError('VALIDATION_ERROR', 'Invalid input data', parsed.error.flatten());
    }

    const { dealId, targetUserId } = parsed.data;
    const deal = await getDealParticipants(dealId);
    
    if (!deal) {
      throw createError('NOT_FOUND_ERROR', 'Deal not found');
    }

    const participants = [deal.requester_id, deal.helper_id];
    
    if (!participants.includes(req.user.userId) || !participants.includes(targetUserId) || req.user.userId === targetUserId) {
      throw createError('AUTHORIZATION_ERROR', 'Forbidden');
    }

    const [existing] = await pool.query(
      `SELECT id FROM contact_exchange_requests
       WHERE deal_id = ? AND requester_id = ? AND target_id = ? LIMIT 1`,
      [dealId, req.user.userId, targetUserId]
    );
    
    if (existing.length) {
      throw createError('CONFLICT_ERROR', 'Request already exists');
    }

    const [result] = await pool.query(
      `INSERT INTO contact_exchange_requests (deal_id, requester_id, target_id, accepted)
       VALUES (?, ?, ?, FALSE)`,
      [dealId, req.user.userId, targetUserId]
    );

    res.status(201).json({ id: result.insertId });
  } catch (error) {
    console.error('Error in contacts request route:', error);
    sendError(res, error);
  }
});

router.post('/respond', requireAuth, async (req, res) => {
  try {
    const parsed = z.object({ 
      requestId: z.number().int().positive(), 
      accept: z.boolean() 
    }).safeParse(req.body);
    
    if (!parsed.success) {
      throw createError('VALIDATION_ERROR', 'Invalid input data', parsed.error.flatten());
    }

    const { requestId, accept } = parsed.data;
    const [rows] = await pool.query(
      `SELECT id, target_id FROM contact_exchange_requests WHERE id = ? LIMIT 1`,
      [requestId]
    );

    const row = rows[0];
    
    if (!row) {
      throw createError('NOT_FOUND_ERROR', 'Request not found');
    }
    
    if (row.target_id !== req.user.userId) {
      throw createError('AUTHORIZATION_ERROR', 'Forbidden');
    }

    if (accept) {
      await pool.query('UPDATE contact_exchange_requests SET accepted = TRUE WHERE id = ?', [requestId]);
      return res.json({ status: 'accepted' });
    }

    await pool.query('DELETE FROM contact_exchange_requests WHERE id = ?', [requestId]);
    res.json({ status: 'rejected' });
  } catch (error) {
    console.error('Error in contacts respond route:', error);
    sendError(res, error);
  }
});

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

    const deal = await getDealParticipants(dealId);
    
    if (!deal) {
      return res.status(404).json({ error: 'Deal not found' });
    }

    const participants = [deal.requester_id, deal.helper_id];
    
    if (!participants.includes(req.user.userId)) {
      return res.status(403).json({ error: 'Forbidden' });
    }

    const [rows] = await pool.query(
      `SELECT cer.id, cer.requester_id, cer.target_id, cer.accepted,
              ru.phone_encrypted AS requester_phone_encrypted,
              tu.phone_encrypted AS target_phone_encrypted
       FROM contact_exchange_requests cer
       JOIN users ru ON ru.id = cer.requester_id
       JOIN users tu ON tu.id = cer.target_id
       WHERE cer.deal_id = ? AND cer.accepted = TRUE`,
      [dealId]
    );

    res.json(rows);
  } catch (error) {
    console.error('Error in contacts deal route:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Add validation for GET /contacts
router.get('/', requireAuth, async (req, res) => {
  try {
    const [rows] = await pool.query(
      `SELECT id, name, email, phone_encrypted FROM contacts WHERE user_id = ?`,
      [req.user.userId]
    );

    res.json(rows);
  } catch (error) {
    console.error('Error in contacts get route:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

export default router;