const express = require('express');
const db = require('../db/models');
const wrapAsync = require('../helpers').wrapAsync;

const router = express.Router();

const WORKSHOP_WHATSAPP = '+5359177041';
const PAYMENT_PROVIDER_LABELS = {
  transfermovil: 'Transfermóvil',
  enzona: 'Enzona',
};

const sanitizeText = (value) => (typeof value === 'string' ? value.trim() : '');

const buildValidationErrors = (data) => {
  const errors = [];

  if (!sanitizeText(data.fullName)) errors.push('El nombre del cliente es obligatorio.');
  if (!sanitizeText(data.contactPhone)) errors.push('El teléfono o WhatsApp es obligatorio.');
  if (!sanitizeText(data.deviceBrand)) errors.push('La marca del equipo es obligatoria.');
  if (!sanitizeText(data.deviceModel)) errors.push('El modelo del equipo es obligatorio.');
  if (!sanitizeText(data.problemDescription) || sanitizeText(data.problemDescription).length < 12) {
    errors.push('Describe el problema con al menos 12 caracteres.');
  }
  if (!['transfermovil', 'enzona'].includes(data.paymentProvider)) {
    errors.push('Selecciona Transfermóvil o Enzona como pasarela de pago.');
  }

  return errors;
};

router.get('/', wrapAsync(async (req, res) => {
  const rows = await db.repair_orders.findAll({
    where: { createdById: req.currentUser.id },
    include: [
      { model: db.customers, as: 'customer' },
      { model: db.devices, as: 'device' },
      { model: db.payments, as: 'payments_repair_order', include: [{ model: db.payment_methods, as: 'payment_method' }] },
      { model: db.whatsapp_notifications, as: 'whatsapp_notifications_repair_order' },
    ],
    order: [['createdAt', 'DESC']],
    limit: 8,
  });

  res.status(200).send({ rows });
}));

router.post('/', wrapAsync(async (req, res) => {
  const data = req.body.data || {};
  const errors = buildValidationErrors(data);

  if (errors.length) {
    return res.status(400).send({ message: errors.join(' ') });
  }

  const fullName = sanitizeText(data.fullName);
  const [firstName, ...restName] = fullName.split(' ');
  const lastName = restName.join(' ');
  const contactPhone = sanitizeText(data.contactPhone);
  const paymentProvider = data.paymentProvider;
  const now = new Date();
  const orderNumber = `FI-${Date.now().toString(36).toUpperCase()}`;
  const paymentReference = `REF-${orderNumber}`;
  const providerLabel = PAYMENT_PROVIDER_LABELS[paymentProvider];

  const transaction = await db.sequelize.transaction();

  try {
    const userUpdate = {};
    if (firstName && !req.currentUser.firstName) userUpdate.firstName = firstName;
    if (lastName && !req.currentUser.lastName) userUpdate.lastName = lastName;
    if (contactPhone && !req.currentUser.phoneNumber) userUpdate.phoneNumber = contactPhone;

    if (Object.keys(userUpdate).length) {
      await db.users.update(userUpdate, { where: { id: req.currentUser.id }, transaction });
    }

    let customer = await db.customers.findOne({
      where: { userId: req.currentUser.id },
      transaction,
    });

    if (!customer) {
      customer = await db.customers.create({
        customer_code: `CLI-${Date.now().toString(36).toUpperCase()}`,
        preferred_contact_channel: 'whatsapp',
        accepts_marketing: Boolean(data.acceptsMarketing),
        userId: req.currentUser.id,
        createdById: req.currentUser.id,
        updatedById: req.currentUser.id,
      }, { transaction });
    } else {
      await customer.update({
        preferred_contact_channel: 'whatsapp',
        accepts_marketing: Boolean(data.acceptsMarketing),
        updatedById: req.currentUser.id,
      }, { transaction });
    }

    const device = await db.devices.create({
      device_type: data.deviceType || 'phone',
      brand: sanitizeText(data.deviceBrand),
      model: sanitizeText(data.deviceModel),
      color: sanitizeText(data.deviceColor),
      accessories_received: sanitizeText(data.accessoriesReceived),
      device_condition: sanitizeText(data.deviceCondition),
      customerId: customer.id,
      createdById: req.currentUser.id,
      updatedById: req.currentUser.id,
    }, { transaction });

    const repairOrder = await db.repair_orders.create({
      order_number: orderNumber,
      source: data.source === 'qr' ? 'qr' : 'public_web',
      status: 'new',
      problem_description: sanitizeText(data.problemDescription),
      internal_notes: `Cliente: ${fullName}\nContacto WhatsApp: ${contactPhone}\nPreferencia de pago: ${providerLabel}`,
      requires_deposit: true,
      deposit_amount: data.depositAmount || 0,
      requested_at: now,
      whatsapp_notified: true,
      customerId: customer.id,
      deviceId: device.id,
      createdById: req.currentUser.id,
      updatedById: req.currentUser.id,
    }, { transaction });

    const [paymentMethod] = await db.payment_methods.findOrCreate({
      where: { provider: paymentProvider },
      defaults: {
        provider: paymentProvider,
        display_name: providerLabel,
        is_enabled: true,
        instructions: `Realiza el pago por ${providerLabel} y conserva el comprobante. Usa la referencia ${paymentReference}.`,
        createdById: req.currentUser.id,
        updatedById: req.currentUser.id,
      },
      transaction,
    });

    const payment = await db.payments.create({
      payment_type: data.depositAmount ? 'deposit' : 'full',
      status: 'pending',
      amount: data.depositAmount || null,
      currency: 'CUP',
      reference_code: paymentReference,
      initiated_at: now,
      notes: `Pago pendiente por ${providerLabel}. El admin debe confirmar cuando reciba el comprobante.`,
      repair_orderId: repairOrder.id,
      payment_methodId: paymentMethod.id,
      createdById: req.currentUser.id,
      updatedById: req.currentUser.id,
    }, { transaction });

    const whatsappMessage = `Nuevo pedido ${orderNumber} - ${fullName} (${contactPhone}). Equipo: ${device.brand} ${device.model}. Problema: ${repairOrder.problem_description}. Pago: ${providerLabel} / ${paymentReference}.`;

    const whatsappNotification = await db.whatsapp_notifications.create({
      event_type: 'order_created',
      to_number: WORKSHOP_WHATSAPP,
      message_body: whatsappMessage,
      status: 'queued',
      queued_at: now,
      repair_orderId: repairOrder.id,
      createdById: req.currentUser.id,
      updatedById: req.currentUser.id,
    }, { transaction });

    await transaction.commit();

    res.status(201).send({
      order: {
        id: repairOrder.id,
        order_number: repairOrder.order_number,
        status: repairOrder.status,
        requested_at: repairOrder.requested_at,
      },
      device: {
        brand: device.brand,
        model: device.model,
      },
      payment: {
        id: payment.id,
        provider: paymentProvider,
        provider_label: providerLabel,
        reference_code: payment.reference_code,
        status: payment.status,
        amount: payment.amount,
        currency: payment.currency,
      },
      whatsapp: {
        id: whatsappNotification.id,
        to_number: WORKSHOP_WHATSAPP,
        status: whatsappNotification.status,
        message_body: whatsappMessage,
      },
    });
  } catch (error) {
    await transaction.rollback();
    throw error;
  }
}));

module.exports = router;
