const { getSettings } = require('../models/settingsModel');
const invoiceModel = require('../models/invoiceModel');
const { calculateLineItem, calculateInvoiceTotals } = require('../services/gstService');
const { amountToWords } = require('../services/amountWordsService');

function normalizeItems(body) {
  const descriptions = Array.isArray(body.description) ? body.description : [body.description];
  const paperTypes = Array.isArray(body.paper_type) ? body.paper_type : [body.paper_type];
  const hsns = Array.isArray(body.hsn_code) ? body.hsn_code : [body.hsn_code];
  const quantities = Array.isArray(body.quantity) ? body.quantity : [body.quantity];
  const rates = Array.isArray(body.rate) ? body.rate : [body.rate];
  const discounts = Array.isArray(body.discount_percent) ? body.discount_percent : [body.discount_percent];
  return descriptions.map((description, index) => ({
    description,
    paper_type: paperTypes[index],
    hsn_code: hsns[index],
    quantity: quantities[index],
    rate: rates[index],
    discount_percent: discounts[index]
  })).filter((item) => item.paper_type && Number(item.quantity) > 0 && Number(item.rate) >= 0);
}

async function createForm(req, res) {
  const settings = await getSettings();
  const invoiceNumber = await invoiceModel.nextInvoicePreview();
  res.render('invoices/create', { title: 'Create Bill', settings, invoiceNumber });
}

async function store(req, res) {
  const settings = await getSettings();
  const rawItems = normalizeItems(req.body);
  if (!rawItems.length) {
    req.flash('error', 'Add at least one invoice item.');
    return res.redirect('/invoices/create');
  }
  const items = rawItems.map((item) => calculateLineItem(item, settings, settings.state_code, req.body.customer_state_code));
  const totals = calculateInvoiceTotals(items);
  const amountInWords = amountToWords(totals.grand_total);
  const invoice = {
    ...req.body,
    show_logo: req.body.show_logo === 'on',
    show_signature: req.body.show_signature === 'on',
    show_seal: req.body.show_seal === 'on',
    consignee_name: req.body.same_as_buyer === 'on' ? req.body.customer_name : req.body.consignee_name,
    consignee_address: req.body.same_as_buyer === 'on' ? req.body.customer_address : req.body.consignee_address,
    consignee_gstin: req.body.same_as_buyer === 'on' ? req.body.customer_gstin : req.body.consignee_gstin,
    consignee_state_name: req.body.same_as_buyer === 'on' ? req.body.customer_state_name : req.body.consignee_state_name,
    consignee_state_code: req.body.same_as_buyer === 'on' ? req.body.customer_state_code : req.body.consignee_state_code
  };
  const id = await invoiceModel.createInvoice(invoice, items, totals, amountInWords);
  req.flash('success', 'Bill created successfully.');
  res.redirect(`/invoices/${id}`);
}

async function list(req, res) {
  const invoices = await invoiceModel.listInvoices(req.query);
  res.render('invoices/list', { title: 'Billing History', invoices, filters: req.query });
}

async function view(req, res) {
  const data = await invoiceModel.getInvoice(req.params.id);
  if (!data) return res.status(404).render('errors/404', { title: 'Invoice not found' });
  res.render('invoices/view', { title: data.invoice.invoice_number, ...data });
}

async function print(req, res) {
  const data = await invoiceModel.getInvoice(req.params.id);
  if (!data) return res.status(404).render('errors/404', { title: 'Invoice not found' });
  const settings = await getSettings();
  res.render('invoices/print', { title: data.invoice.invoice_number, settings, ...data, layout: false });
}

async function cancel(req, res) {
  await invoiceModel.cancelInvoice(req.params.id);
  req.flash('success', 'Invoice cancelled.');
  res.redirect('/invoices');
}

module.exports = { createForm, store, list, view, print, cancel };
