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

// Generate IPC Number
const generateIPCNumber = async (companyId, fiscalYearId = null) => {
  try {
    const generatedNumber = await generateNextNumber(companyId, 'IN_PROCESS_CHECKLIST', null, fiscalYearId);
    return generatedNumber;
  } catch (error) {
    console.warn('Number format not found, using fallback method:', error.message);
    const today = new Date();
    const year = today.getFullYear();
    const prefix = `IPC${year}`;
    
    const lastIPC = await db.InProcessCheckList.findOne({
      where: {
        company_id: companyId,
        ipc_no: { [Op.like]: `${prefix}%` }
      },
      order: [['ipc_no', 'DESC']]
    });

    let sequence = 1;
    if (lastIPC) {
      const lastSequence = parseInt(lastIPC.ipc_no.slice(-4)) || 0;
      sequence = lastSequence + 1;
    }

    return `${prefix}${sequence.toString().padStart(4, '0')}`;
  }
};

// Get all In-Process CheckLists
exports.getAll = asyncHandler(async (req, res) => {
  const {
    page = 1,
    limit = 25,
    search = '',
    company_id,
    plant_id,
    fiscal_year_id,
    customer_id,
    status,
    date_from,
    date_to
  } = req.query;

  const offset = (page - 1) * limit;
  const where = {};

  if (company_id) where.company_id = company_id;
  if (plant_id) where.plant_id = plant_id;
  if (fiscal_year_id) where.fiscal_year_id = fiscal_year_id;
  if (customer_id) where.customer_id = customer_id;
  if (status) where.status = status;

  if (date_from && date_to) {
    where.ipc_date = { [Op.between]: [date_from, date_to] };
  } else if (date_from) {
    where.ipc_date = { [Op.gte]: date_from };
  } else if (date_to) {
    where.ipc_date = { [Op.lte]: date_to };
  }

  if (search) {
    where[Op.or] = [
      { ipc_no: { [Op.like]: `%${search}%` } },
      { work_order_no: { [Op.like]: `%${search}%` } },
      { customer_name: { [Op.like]: `%${search}%` } },
      { model: { [Op.like]: `%${search}%` } }
    ];
  }

  const { count, rows } = await db.InProcessCheckList.findAndCountAll({
    where,
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.Plant,
        as: 'plant',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.FiscalYear,
        as: 'fiscalYear',
        attributes: ['id', 'fiscal_year', 'start_date', 'end_date']
      },
      {
        model: db.BusinessPartner,
        as: 'customer',
        attributes: ['id', 'bp_number', 'name', 'legal_name']
      },
      {
        model: db.User,
        as: 'creator',
        attributes: ['id', 'username', 'email']
      }
    ],
    limit: parseInt(limit),
    offset: parseInt(offset),
    order: [['ipc_date', 'DESC'], ['id', 'DESC']],
    distinct: true
  });

  return sendSuccess(
    res,
    'In-Process CheckLists fetched successfully',
    {
      items: rows,
      pagination: {
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        pages: Math.ceil(count / limit)
      }
    }
  );
});

// Get by ID
exports.getById = asyncHandler(async (req, res) => {
  const { id } = req.params;

  const checkList = await db.InProcessCheckList.findByPk(id, {
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.Plant,
        as: 'plant',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.FiscalYear,
        as: 'fiscalYear',
        attributes: ['id', 'fiscal_year', 'start_date', 'end_date']
      },
      {
        model: db.BusinessPartner,
        as: 'customer',
        attributes: ['id', 'bp_number', 'name', 'legal_name']
      },
      {
        model: db.InProcessCheckListDetail,
        as: 'details',
        order: [['line_no', 'ASC']]
      },
      {
        model: db.User,
        as: 'creator',
        attributes: ['id', 'username', 'email']
      },
      {
        model: db.User,
        as: 'updater',
        attributes: ['id', 'username', 'email']
      }
    ]
  });

  if (!checkList) {
    return sendError(res, 'In-Process CheckList not found', 404);
  }

  return sendSuccess(res, 'In-Process CheckList fetched successfully', checkList);
});

// Create
exports.create = asyncHandler(async (req, res) => {
  const userId = req.user?.id;
  const transaction = await db.sequelize.transaction();

  try {
    const { details, ...headerData } = req.body;

    // Generate IPC Number if not provided
    if (!headerData.ipc_no) {
      headerData.ipc_no = await generateIPCNumber(
        headerData.company_id,
        headerData.fiscal_year_id
      );
    }

    // Create checklist header
    const checkList = await db.InProcessCheckList.create({
      ...headerData,
      created_by: userId,
      updated_by: userId
    }, { transaction });

    // Create checklist details if provided
    if (details && Array.isArray(details) && details.length > 0) {
      const detailsWithIPCId = details.map(detail => ({
        ...detail,
        ipc_id: checkList.id
      }));
      await db.InProcessCheckListDetail.bulkCreate(detailsWithIPCId, { transaction });
    }

    await transaction.commit();

    // Fetch the created checklist with all associations
    const createdCheckList = await db.InProcessCheckList.findByPk(checkList.id, {
      include: [
        {
          model: db.Company,
          as: 'company',
          attributes: ['id', 'code', 'name']
        },
        {
          model: db.Plant,
          as: 'plant',
          attributes: ['id', 'code', 'name']
        },
        {
          model: db.FiscalYear,
          as: 'fiscalYear',
          attributes: ['id', 'fiscal_year']
        },
        {
          model: db.BusinessPartner,
          as: 'customer',
          attributes: ['id', 'bp_number', 'name']
        },
        {
          model: db.InProcessCheckListDetail,
          as: 'details',
          order: [['line_no', 'ASC']]
        }
      ]
    });

    return sendSuccess(res, 'In-Process CheckList created successfully', createdCheckList, null, 201);
  } catch (error) {
    await transaction.rollback();
    throw error;
  }
});

// Update
exports.update = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const userId = req.user?.id;
  const transaction = await db.sequelize.transaction();

  try {
    const checkList = await db.InProcessCheckList.findByPk(id);

    if (!checkList) {
      await transaction.rollback();
      return sendError(res, 'In-Process CheckList not found', 404);
    }

    const { details, ...headerData } = req.body;

    // Update checklist header
    await checkList.update({
      ...headerData,
      updated_by: userId
    }, { transaction });

    // Update details if provided
    if (details && Array.isArray(details)) {
      // Delete existing details
      await db.InProcessCheckListDetail.destroy({
        where: { ipc_id: id },
        transaction
      });

      // Create new details
      if (details.length > 0) {
        const detailsWithIPCId = details.map(detail => ({
          ...detail,
          ipc_id: id
        }));
        await db.InProcessCheckListDetail.bulkCreate(detailsWithIPCId, { transaction });
      }
    }

    await transaction.commit();

    // Fetch the updated checklist with all associations
    const updatedCheckList = await db.InProcessCheckList.findByPk(id, {
      include: [
        {
          model: db.Company,
          as: 'company',
          attributes: ['id', 'code', 'name']
        },
        {
          model: db.Plant,
          as: 'plant',
          attributes: ['id', 'code', 'name']
        },
        {
          model: db.FiscalYear,
          as: 'fiscalYear',
          attributes: ['id', 'fiscal_year']
        },
        {
          model: db.BusinessPartner,
          as: 'customer',
          attributes: ['id', 'bp_number', 'name']
        },
        {
          model: db.InProcessCheckListDetail,
          as: 'details',
          order: [['line_no', 'ASC']]
        }
      ]
    });

    return sendSuccess(res, 'In-Process CheckList updated successfully', updatedCheckList);
  } catch (error) {
    await transaction.rollback();
    throw error;
  }
});

// Delete
exports.delete = asyncHandler(async (req, res) => {
  const { id } = req.params;

  try {
    const checkList = await db.InProcessCheckList.findByPk(id);

    if (!checkList) {
      return sendError(res, 'In-Process CheckList not found', 404);
    }

    // Delete checklist (details will be cascade deleted)
    await checkList.destroy();

    return sendSuccess(res, 'In-Process CheckList deleted successfully');
  } catch (error) {
    throw error;
  }
});

module.exports = exports;
