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 CCR Number
const generateCCRNumber = async (companyId, fiscalYearId = null) => {
  try {
    const generatedNumber = await generateNextNumber(companyId, 'CUSTOMER_COMPLAINT_REGISTER', 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 = `CCR${year}`;
    
    const lastCCR = await db.CustomerComplaintRegister.findOne({
      where: {
        company_id: companyId,
        ccr_no: { [Op.like]: `${prefix}%` }
      },
      order: [['ccr_no', 'DESC']]
    });

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

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

// Get all Customer Complaint Registers
exports.getAll = asyncHandler(async (req, res) => {
  const {
    page = 1,
    limit = 25,
    search = '',
    company_id,
    plant_id,
    fiscal_year_id,
    customer_id,
    status,
    closure_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 (closure_status) where.closure_status = closure_status;

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

  if (search) {
    where[Op.or] = [
      { ccr_no: { [Op.like]: `%${search}%` } },
      { customer_name: { [Op.like]: `%${search}%` } },
      { part_name: { [Op.like]: `%${search}%` } },
      { part_no: { [Op.like]: `%${search}%` } },
      { car_ref_no: { [Op.like]: `%${search}%` } }
    ];
  }

  const { count, rows } = await db.CustomerComplaintRegister.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.Material,
        as: 'material',
        attributes: ['id', 'material_number', 'description']
      },
      {
        model: db.User,
        as: 'assignedUser',
        attributes: ['id', 'username', 'email']
      },
      {
        model: db.User,
        as: 'creator',
        attributes: ['id', 'username', 'email']
      }
    ],
    limit: parseInt(limit),
    offset: parseInt(offset),
    order: [['ccr_date', 'DESC'], ['id', 'DESC']],
    distinct: true
  });

  return sendSuccess(
    res,
    'Customer Complaint Registers 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 complaint = await db.CustomerComplaintRegister.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.Material,
        as: 'material',
        attributes: ['id', 'material_number', 'description']
      },
      {
        model: db.User,
        as: 'assignedUser',
        attributes: ['id', 'username', 'email']
      },
      {
        model: db.User,
        as: 'creator',
        attributes: ['id', 'username', 'email']
      },
      {
        model: db.User,
        as: 'updater',
        attributes: ['id', 'username', 'email']
      }
    ]
  });

  if (!complaint) {
    return sendError(res, 'Customer Complaint Register not found', 404);
  }

  return sendSuccess(res, 'Customer Complaint Register fetched successfully', complaint);
});

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

  try {
    const headerData = req.body;

    // Generate CCR Number if not provided
    if (!headerData.ccr_no) {
      headerData.ccr_no = await generateCCRNumber(
        headerData.company_id,
        headerData.fiscal_year_id
      );
    }

    // Set default document number if not provided
    if (!headerData.doc_no) {
      headerData.doc_no = 'RI/QA/F/08';
    }

    // Create complaint record
    const complaint = await db.CustomerComplaintRegister.create({
      ...headerData,
      created_by: userId,
      updated_by: userId
    });

    // Fetch the created complaint with all associations
    const createdComplaint = await db.CustomerComplaintRegister.findByPk(complaint.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.Material,
          as: 'material',
          attributes: ['id', 'material_number', 'description']
        }
      ]
    });

    return sendSuccess(res, 'Customer Complaint Register created successfully', createdComplaint, null, 201);
  } catch (error) {
    throw error;
  }
});

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

  try {
    const complaint = await db.CustomerComplaintRegister.findByPk(id);

    if (!complaint) {
      return sendError(res, 'Customer Complaint Register not found', 404);
    }

    const headerData = req.body;

    // Update complaint
    await complaint.update({
      ...headerData,
      updated_by: userId
    });

    // Fetch the updated complaint with all associations
    const updatedComplaint = await db.CustomerComplaintRegister.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.Material,
        as: 'material',
        attributes: ['id', 'material_number', 'description']
      },
      {
        model: db.User,
        as: 'assignedUser',
        attributes: ['id', 'username', 'email']
      }
    ]
  });

  return sendSuccess(res, 'Customer Complaint Register updated successfully', updatedComplaint);
  } catch (error) {
    throw error;
  }
});

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

  try {
    const complaint = await db.CustomerComplaintRegister.findByPk(id);

    if (!complaint) {
      return sendError(res, 'Customer Complaint Register not found', 404);
    }

    // Delete complaint
    await complaint.destroy();

    return sendSuccess(res, 'Customer Complaint Register deleted successfully');
  } catch (error) {
    throw error;
  }
});

// Get by Customer
exports.getByCustomer = asyncHandler(async (req, res) => {
  const { customerId } = req.params;

  const complaints = await db.CustomerComplaintRegister.findAll({
    where: { customer_id: customerId },
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.Plant,
        as: 'plant',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.BusinessPartner,
        as: 'customer',
        attributes: ['id', 'bp_number', 'name', 'legal_name']
      }
    ],
    order: [['ccr_date', 'DESC']]
  });

  return sendSuccess(res, 'Customer Complaint Registers fetched successfully', complaints);
});

module.exports = exports;
