const db = require('../models');
const { sendResponse } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const { getPagination, getPagingData } = require('../utils/pagination');
const { Op } = require('sequelize');

const Company = db.Company;
const Currency = db.Currency;
const City = db.City;
const State = db.State;
const Country = db.Country;

exports.getAll = asyncHandler(async (req, res) => {
  const { page = 1, limit = 10, search, status } = req.query;
  const { limit: limitNum, offset } = getPagination(page, limit);

  const where = {};
  if (search) {
    where[Op.or] = [
      { code: { [Op.like]: `%${search}%` } },
      { name: { [Op.like]: `%${search}%` } },
      { legal_name: { [Op.like]: `%${search}%` } },
    ];
  }
  if (status) {
    where.status = status;
  }

  const companies = await Company.findAndCountAll({
    where,
    include: [
      { model: Currency, as: 'currency', attributes: ['id', 'currency_code', 'currency_name'] },
      { model: City, as: 'city', attributes: ['id', 'city_name'] },
      { model: State, as: 'state', attributes: ['id', 'state_name', 'state_code'] },
      { model: Country, as: 'country', attributes: ['id', 'country_name', 'country_code'] },
    ],
    limit: limitNum,
    offset,
    order: [['code', 'ASC']],
  });

  const response = getPagingData(companies, page, limitNum);
  sendResponse(res, 200, true, 'Companies retrieved successfully', response);
});

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

  const company = await Company.findByPk(id, {
    include: [
      { model: Currency, as: 'currency', attributes: ['id', 'currency_code', 'currency_name'] },
      { model: City, as: 'city', attributes: ['id', 'city_name'] },
      { model: State, as: 'state', attributes: ['id', 'state_name', 'state_code', 'gst_state_code'] },
      { model: Country, as: 'country', attributes: ['id', 'country_name', 'country_code'] },
    ],
  });

  if (!company) {
    return sendResponse(res, 404, false, 'Company not found', null);
  }

  sendResponse(res, 200, true, 'Company retrieved successfully', company);
});

exports.create = asyncHandler(async (req, res) => {
  const data = req.body;
  data.created_by = req.user.userId;
  data.updated_by = req.user.userId;

  // Convert empty strings to null for foreign key fields to avoid constraint errors
  const foreignKeyFields = ['country_id', 'state_id', 'city_id', 'currency_id'];
  foreignKeyFields.forEach(field => {
    if (data[field] === '' || data[field] === undefined) {
      data[field] = null;
    } else if (data[field] != null) {
      // Ensure it's a valid integer
      const numValue = Number(data[field]);
      data[field] = Number.isNaN(numValue) ? null : numValue;
    }
  });

  const company = await Company.create(data);
  sendResponse(res, 201, true, 'Company created successfully', company);
});

exports.update = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const data = req.body;
  data.updated_by = req.user.userId;

  // Convert empty strings to null for foreign key fields to avoid constraint errors
  const foreignKeyFields = ['country_id', 'state_id', 'city_id', 'currency_id'];
  foreignKeyFields.forEach(field => {
    if (data[field] === '' || data[field] === undefined) {
      data[field] = null;
    } else if (data[field] != null) {
      // Ensure it's a valid integer
      const numValue = Number(data[field]);
      data[field] = Number.isNaN(numValue) ? null : numValue;
    }
  });

  const company = await Company.findByPk(id);
  if (!company) {
    return sendResponse(res, 404, false, 'Company not found', null);
  }

  await company.update(data);
  sendResponse(res, 200, true, 'Company updated successfully', company);
});

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

  const company = await Company.findByPk(id);
  if (!company) {
    return sendResponse(res, 404, false, 'Company not found', null);
  }

  await company.update({ status: 'INACTIVE', updated_by: req.user.userId });
  sendResponse(res, 200, true, 'Company deactivated successfully', null);
});

