import { fail, redirect } from '@sveltejs/kit';
import { listParts } from '$lib/server/parts.js';
import {
  getOrCreatePendingInvoice,
  addLine,
  addCustomLine,
  updateLine,
  removeLine,
  saveInvoice,
  cancelInvoice
} from '$lib/server/invoices.js';

export function load() {
  const { invoice, lines } = getOrCreatePendingInvoice();
  return {
    invoice,
    lines,
    parts: listParts()
  };
}

function toDirams(value) {
  if (value === '' || value == null) return 0;
  const num = typeof value === 'number' ? value : Number(String(value).replace(',', '.'));
  if (!Number.isFinite(num)) return 0;
  return Math.round(num * 100);
}

export const actions = {
  add_part_line: async ({ request }) => {
    const data = Object.fromEntries(await request.formData());
    const errors = {};
    if (!data.part_id)    errors.add_part = 'invoices.errors.part_required';
    const qty = Number(data.quantity);
    if (!Number.isInteger(qty) || qty <= 0) errors.add_part = 'invoices.errors.quantity_required';
    if (Object.keys(errors).length) return fail(400, { errors, values: data });

    const { invoice } = getOrCreatePendingInvoice();
    try {
      addLine({
        invoice_id: invoice.id,
        part_id: data.part_id,
        quantity: qty,
        unit_price_dirams: data.unit_price === '' || data.unit_price == null ? null : toDirams(data.unit_price)
      });
    } catch (err) {
      return fail(400, { errors: { add_part: 'invoices.errors.add_failed' }, values: data, errMsg: String(err.message) });
    }
    return { ok: true };
  },

  add_custom_line: async ({ request }) => {
    const data = Object.fromEntries(await request.formData());
    const errors = {};
    const label = (data.label || '').trim();
    const qty   = Number(data.quantity);
    if (!label) errors.add_custom = 'invoices.errors.label_required';
    if (!Number.isInteger(qty) || qty <= 0) errors.add_custom = 'invoices.errors.quantity_required';
    if (Object.keys(errors).length) return fail(400, { errors, values: data });

    const { invoice } = getOrCreatePendingInvoice();
    addCustomLine({
      invoice_id: invoice.id,
      label,
      quantity: qty,
      unit_price_dirams: toDirams(data.unit_price)
    });
    return { ok: true };
  },

  update_line: async ({ request }) => {
    const data = Object.fromEntries(await request.formData());
    const id  = Number(data.line_id);
    const qty = Number(data.quantity);
    if (!id) return fail(400, { errors: { line: 'invoices.errors.line_missing' } });
    if (!Number.isInteger(qty) || qty <= 0) {
      return fail(400, { errors: { [`line_${id}`]: 'invoices.errors.quantity_required' } });
    }
    try {
      updateLine(id, {
        quantity: qty,
        unit_price_dirams: data.unit_price === '' || data.unit_price == null ? null : toDirams(data.unit_price),
        label: data.label
      });
    } catch (err) {
      return fail(400, { errors: { [`line_${id}`]: 'invoices.errors.update_failed' }, errMsg: String(err.message) });
    }
    return { ok: true };
  },

  remove_line: async ({ request }) => {
    const data = Object.fromEntries(await request.formData());
    const id = Number(data.line_id);
    if (id) removeLine(id);
    return { ok: true };
  },

  save_invoice: async () => {
    const { invoice, lines } = getOrCreatePendingInvoice();
    if (lines.length === 0) {
      return fail(400, { errors: { save: 'invoices.errors.empty' } });
    }
    let savedId;
    try {
      savedId = saveInvoice(invoice.id);
    } catch (err) {
      const msg = String(err.message);
      if (msg.includes('not enough stock')) {
        return fail(400, { errors: { save: 'invoices.errors.not_enough_stock' }, errMsg: msg });
      }
      return fail(400, { errors: { save: 'invoices.errors.save_failed' }, errMsg: msg });
    }
    throw redirect(303, `/invoices/${savedId}`);
  },

  cancel_invoice: async () => {
    const { invoice } = getOrCreatePendingInvoice();
    cancelInvoice(invoice.id);
    throw redirect(303, '/invoices/new');
  }
};
