const db = require('../models');
const { sendSuccess, sendError } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const { Op } = require('sequelize');

exports.getAll = asyncHandler(async (req, res) => {
  const { page = 1, limit = 10, search = '', startDate, endDate } = req.query;
  const offset = (parseInt(page, 10) - 1) * parseInt(limit, 10);
  const where = {};

  if (req.user?.company_id) {
    where.company_id = req.user.company_id;
  }

  if (search) {
    where[Op.or] = [
      { history_card_no: { [Op.like]: `%${search}%` } },
      { instrument_description: { [Op.like]: `%${search}%` } },
      { make: { [Op.like]: `%${search}%` } },
      { serial_number: { [Op.like]: `%${search}%` } },
      { location: { [Op.like]: `%${search}%` } }
    ];
  }

  if (startDate && endDate) {
    where.card_date = { [Op.between]: [startDate, endDate] };
  } else if (startDate) {
    where.card_date = { [Op.gte]: startDate };
  } else if (endDate) {
    where.card_date = { [Op.lte]: endDate };
  }

  const { count, rows } = await db.MeasuringInstrumentHistoryCard.findAndCountAll({
    where,
    limit: parseInt(limit, 10),
    offset,
    order: [['card_date', 'DESC'], ['id', 'DESC']],
    distinct: true
  });

  return sendSuccess(res, 'Measuring instrument history cards fetched successfully', {
    data: rows,
    pagination: {
      total: count,
      page: parseInt(page, 10),
      limit: parseInt(limit, 10),
      totalPages: Math.ceil(count / parseInt(limit, 10))
    }
  });
});

exports.getById = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const where = { id };
  if (req.user?.company_id) {
    where.company_id = req.user.company_id;
  }
  const card = await db.MeasuringInstrumentHistoryCard.findOne({
    where,
    include: [
      { model: db.MeasuringInstrumentHistoryCardDetail, as: 'details', order: [['line_no', 'ASC']] }
    ]
  });
  if (!card) return sendError(res, 'Measuring instrument history card not found', 404);
  return sendSuccess(res, 'History card fetched successfully', card);
});

exports.create = asyncHandler(async (req, res) => {
  const userId = req.user?.id;
  const transaction = await db.sequelize.transaction();
  try {
    const { details = [], ...header } = req.body;
    const card = await db.MeasuringInstrumentHistoryCard.create({
      ...header,
      created_by: userId,
      updated_by: userId
    }, { transaction });
    if (details.length > 0) {
      await db.MeasuringInstrumentHistoryCardDetail.bulkCreate(
        details.map((d) => ({ ...d, history_card_id: card.id })),
        { transaction }
      );
    }
    await transaction.commit();
    const created = await db.MeasuringInstrumentHistoryCard.findByPk(card.id, {
      include: [{ model: db.MeasuringInstrumentHistoryCardDetail, as: 'details', order: [['line_no', 'ASC']] }]
    });
    return sendSuccess(res, 'Measuring instrument history card created successfully', created, null, 201);
  } catch (err) {
    await transaction.rollback();
    throw err;
  }
});

exports.update = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const userId = req.user?.id;
  const where = { id };
  if (req.user?.company_id) {
    where.company_id = req.user.company_id;
  }
  const card = await db.MeasuringInstrumentHistoryCard.findOne({ where });
  if (!card) return sendError(res, 'Measuring instrument history card not found', 404);
  const transaction = await db.sequelize.transaction();
  try {
    const { details, ...header } = req.body;
    await card.update({ ...header, updated_by: userId }, { transaction });
    await db.MeasuringInstrumentHistoryCardDetail.destroy({ where: { history_card_id: id }, transaction });
    if (details && details.length > 0) {
      await db.MeasuringInstrumentHistoryCardDetail.bulkCreate(
        details.map((d) => ({ ...d, history_card_id: parseInt(id, 10) })),
        { transaction }
      );
    }
    await transaction.commit();
    const updated = await db.MeasuringInstrumentHistoryCard.findByPk(id, {
      include: [{ model: db.MeasuringInstrumentHistoryCardDetail, as: 'details', order: [['line_no', 'ASC']] }]
    });
    return sendSuccess(res, 'Measuring instrument history card updated successfully', updated);
  } catch (err) {
    await transaction.rollback();
    throw err;
  }
});

exports.delete = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const where = { id };
  if (req.user?.company_id) {
    where.company_id = req.user.company_id;
  }
  const card = await db.MeasuringInstrumentHistoryCard.findOne({ where });
  if (!card) return sendError(res, 'Measuring instrument history card not found', 404);
  await card.destroy();
  return sendSuccess(res, 'Measuring instrument history card deleted successfully');
});
