/**
 * Controller employé
 */
import { pool } from '../../db.js';
import { AppError, asyncHandler } from '../middleware/errorHandler.js';

/**
 * Récupérer les tickets en attente de validation
 * GET /api/employee/pending-tickets
 */
export const getPendingTickets = asyncHandler(async (req, res) => {
  const { page = 1, limit = 20 } = req.query;
  const offset = (page - 1) * limit;

  const result = await pool.query(
    `SELECT
      t.id,
      t.code,
      t.status,
      t.played_at,
      u.id as user_id,
      u.email as user_email,
      u.first_name as user_first_name,
      u.last_name as user_last_name,
      u.phone as user_phone,
      p.id as prize_id,
      p.name as prize_name,
      p.type as prize_type,
      p.value as prize_value,
      p.description as prize_description
    FROM tickets t
    JOIN users u ON t.user_id = u.id
    JOIN prizes p ON t.prize_id = p.id
    WHERE t.status = 'PENDING'
    ORDER BY t.played_at ASC
    LIMIT $1 OFFSET $2`,
    [limit, offset]
  );

  // Compter le total
  const countResult = await pool.query(
    'SELECT COUNT(*) FROM tickets WHERE status = $1',
    ['PENDING']
  );

  const total = parseInt(countResult.rows[0].count);

  // Transform data to match frontend expectations
  const transformedData = result.rows.map(row => ({
    id: row.id,
    code: row.code,
    status: row.status,
    playedAt: row.played_at,
    user: {
      id: row.user_id,
      email: row.user_email,
      firstName: row.user_first_name,
      lastName: row.user_last_name,
      phone: row.user_phone,
    },
    prize: {
      id: row.prize_id,
      name: row.prize_name,
      type: row.prize_type,
      value: row.prize_value,
      description: row.prize_description,
    },
  }));

  res.json({
    success: true,
    data: transformedData,
    pagination: {
      total,
      page: parseInt(page),
      limit: parseInt(limit),
      totalPages: Math.ceil(total / limit),
    },
  });
});

/**
 * Rechercher un ticket par code
 * GET /api/employee/search-ticket
 */
export const searchTicket = asyncHandler(async (req, res, next) => {
  const { code } = req.query;

  const result = await pool.query(
    `SELECT
      t.id,
      t.code,
      t.status,
      t.played_at,
      t.claimed_at,
      t.validated_at,
      t.rejection_reason,
      u.id as user_id,
      u.email as user_email,
      u.first_name || ' ' || u.last_name as user_name,
      u.phone as user_phone,
      p.id as prize_id,
      p.name as prize_name,
      p.type as prize_type,
      p.value as prize_value,
      p.description as prize_description,
      v.first_name || ' ' || v.last_name as validated_by_name
    FROM tickets t
    JOIN users u ON t.user_id = u.id
    JOIN prizes p ON t.prize_id = p.id
    LEFT JOIN users v ON t.validated_by = v.id
    WHERE t.code = $1`,
    [code]
  );

  if (result.rows.length === 0) {
    return next(new AppError('Ticket non trouvé', 404));
  }

  res.json({
    success: true,
    data: result.rows[0],
  });
});

/**
 * Valider ou rejeter un ticket
 * POST /api/employee/validate-ticket
 */
export const validateTicket = asyncHandler(async (req, res, next) => {
  const { ticketId, action, rejectionReason } = req.body;
  const employeeId = req.user.id;

  // Récupérer le ticket
  const ticketResult = await pool.query(
    'SELECT id, status, user_id FROM tickets WHERE id = $1',
    [ticketId]
  );

  if (ticketResult.rows.length === 0) {
    return next(new AppError('Ticket non trouvé', 404));
  }

  const ticket = ticketResult.rows[0];

  if (ticket.status !== 'PENDING') {
    return next(new AppError('Ce ticket a déjà été traité', 400));
  }

  const client = await pool.connect();

  try {
    await client.query('BEGIN');

    if (action === 'APPROVE') {
      // Approuver le ticket
      await client.query(
        `UPDATE tickets
         SET status = 'CLAIMED',
             validated_by = $1,
             validated_at = CURRENT_TIMESTAMP,
             claimed_at = CURRENT_TIMESTAMP
         WHERE id = $2`,
        [employeeId, ticketId]
      );

      await client.query('COMMIT');

      res.json({
        success: true,
        message: 'Ticket validé avec succès',
      });
    } else if (action === 'REJECT') {
      // Rejeter le ticket
      await client.query(
        `UPDATE tickets
         SET status = 'REJECTED',
             validated_by = $1,
             validated_at = CURRENT_TIMESTAMP,
             rejection_reason = $2
         WHERE id = $3`,
        [employeeId, rejectionReason, ticketId]
      );

      // Incrémenter le stock du prix (le prix est remis en circulation)
      await client.query(
        'UPDATE prizes SET stock = stock + 1 WHERE id = (SELECT prize_id FROM tickets WHERE id = $1)',
        [ticketId]
      );

      await client.query('COMMIT');

      res.json({
        success: true,
        message: 'Ticket rejeté',
      });
    }
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
});

/**
 * Statistiques pour l'employé
 * GET /api/employee/stats
 */
export const getEmployeeStats = asyncHandler(async (req, res) => {
  const employeeId = req.user.id;

  const result = await pool.query(
    `SELECT
      COUNT(*) as total_validated,
      COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_approved,
      COUNT(CASE WHEN status = 'REJECTED' THEN 1 END) as total_rejected
    FROM tickets
    WHERE validated_by = $1`,
    [employeeId]
  );

  // Statistiques pour aujourd'hui
  const todayResult = await pool.query(
    `SELECT
      COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as claimed_today
    FROM tickets
    WHERE validated_by = $1
      AND DATE(validated_at) = CURRENT_DATE`,
    [employeeId]
  );

  const pendingResult = await pool.query(
    'SELECT COUNT(*) as pending_count FROM tickets WHERE status = $1',
    ['PENDING']
  );

  res.json({
    success: true,
    data: {
      ...result.rows[0],
      claimed_today: parseInt(todayResult.rows[0].claimed_today) || 0,
      pending_tickets: parseInt(pendingResult.rows[0].pending_count),
    },
  });
});

/**
 * Rechercher tous les gains d'un client
 * GET /api/employee/client-prizes
 */
export const getClientPrizes = asyncHandler(async (req, res) => {
  const { email, phone } = req.query;

  if (!email && !phone) {
    throw new AppError('Email ou téléphone requis', 400);
  }

  // Chercher l'utilisateur
  let userQuery = 'SELECT id, email, first_name, last_name, phone FROM users WHERE role = $1';
  const params = ['CLIENT'];

  if (email) {
    userQuery += ' AND email ILIKE $2';
    params.push(`%${email}%`);
  } else if (phone) {
    userQuery += ' AND phone ILIKE $2';
    params.push(`%${phone}%`);
  }

  const userResult = await pool.query(userQuery, params);

  if (userResult.rows.length === 0) {
    throw new AppError('Client non trouvé', 404);
  }

  const user = userResult.rows[0];

  // Récupérer tous les tickets gagnants du client
  const ticketsResult = await pool.query(
    `SELECT
      t.id,
      t.code,
      t.status,
      t.played_at,
      t.claimed_at,
      t.validated_at,
      p.id as prize_id,
      p.name as prize_name,
      p.type as prize_type,
      p.value as prize_value,
      p.description as prize_description,
      v.first_name || ' ' || v.last_name as validated_by_name
    FROM tickets t
    JOIN prizes p ON t.prize_id = p.id
    LEFT JOIN users v ON t.validated_by = v.id
    WHERE t.user_id = $1 AND t.played_at IS NOT NULL
    ORDER BY t.played_at DESC`,
    [user.id]
  );

  res.json({
    success: true,
    data: {
      client: {
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        phone: user.phone,
      },
      prizes: ticketsResult.rows.map((t) => ({
        ticketId: t.id,
        ticketCode: t.code,
        status: t.status,
        playedAt: t.played_at,
        claimedAt: t.claimed_at,
        validatedAt: t.validated_at,
        validatedBy: t.validated_by_name,
        prize: {
          id: t.prize_id,
          name: t.prize_name,
          type: t.prize_type,
          value: t.prize_value,
          description: t.prize_description,
        },
      })),
      totalPrizes: ticketsResult.rows.length,
      pendingPrizes: ticketsResult.rows.filter((t) => t.status === 'PENDING').length,
      claimedPrizes: ticketsResult.rows.filter((t) => t.status === 'CLAIMED').length,
    },
  });
});

/**
 * Historique des validations de l'employé
 * GET /api/employee/history
 */
export const getEmployeeHistory = asyncHandler(async (req, res) => {
  const employeeId = req.user.id;

  const result = await pool.query(
    `SELECT
      t.id,
      t.code,
      t.status,
      t.played_at,
      t.claimed_at,
      t.validated_at,
      t.rejection_reason,
      u.email as user_email,
      u.first_name || ' ' || u.last_name as user_name,
      p.name as prize_name,
      p.value as prize_value
    FROM tickets t
    JOIN users u ON t.user_id = u.id
    JOIN prizes p ON t.prize_id = p.id
    WHERE t.validated_by = $1
    ORDER BY t.validated_at DESC`,
    [employeeId]
  );

  res.json({
    success: true,
    data: result.rows,
  });
});

export default {
  getPendingTickets,
  searchTicket,
  validateTicket,
  getEmployeeStats,
  getClientPrizes,
  getEmployeeHistory,
};
