const express = require('express');
const { requireCapability } = require('../middleware/auth');
const close = require('../services/closePeriods');

const router = express.Router();
const reader = requireCapability('finance.view');
const closer = requireCapability('finance.close');

// Period close (month-end / year-end). All scoped to the active company (req.companyId).

router.get('/close-periods', reader, (req, res) => {
  res.json({ periods: close.listPeriods(req.companyId, req.query.book || null) });
});

// Step definitions for the wizard (month vs year).
router.get('/close-periods/step-defs', reader, (req, res) => {
  res.json({ month: close.stepDefs('month'), year: close.stepDefs('year') });
});

router.post('/close-periods/start', closer, (req, res, next) => {
  try {
    const period = close.getOrStart(req.companyId, req.body.book, req.body.period_type || 'month', req.body.fiscal_year, req.body.period_month, req.user.id);
    res.status(201).json({ period, steps: close.stepDefs(period.period_type) });
  } catch (error) {
    next(error);
  }
});

router.get('/close-periods/:id', reader, (req, res) => {
  const period = close.getPeriod(req.params.id, req.companyId);
  if (!period) return res.status(404).json({ error: 'Close period not found' });
  return res.json({ period, steps: close.stepDefs(period.period_type), data: close.stepData(period, req.companyId) });
});

function withPeriod(handler) {
  return (req, res, next) => {
    const period = close.getPeriod(req.params.id, req.companyId);
    if (!period) return res.status(404).json({ error: 'Close period not found' });
    try {
      return handler(period, req, res);
    } catch (error) {
      return next(error);
    }
  };
}

router.post('/close-periods/:id/steps/:key', closer, withPeriod((period, req, res) => {
  res.json({ period: close.recordStep(period.id, req.params.key, req.body || {}, req.user.id, req.companyId) });
}));

router.post('/close-periods/:id/post-depreciation', closer, withPeriod((period, req, res) => {
  const summary = close.postDepreciation(period, req.user.id, req.companyId);
  res.json({ summary, period: close.getPeriod(period.id, req.companyId) });
}));

router.post('/close-periods/:id/post-disposals', closer, withPeriod((period, req, res) => {
  res.json({ result: close.postDisposalEntries(period, req.user.id, req.companyId) });
}));

router.post('/close-periods/:id/reconcile', closer, withPeriod((period, req, res) => {
  const reconciliation = close.reconcile(period, req.companyId);
  res.json({ reconciliation, period: close.getPeriod(period.id, req.companyId) });
}));

router.post('/close-periods/:id/wip/:assetId/capitalize', closer, withPeriod((period, req, res) => {
  const asset = close.capitalizeWip(Number(req.params.assetId), req.body || {}, req.user.id, req.companyId);
  if (!asset) return res.status(404).json({ error: 'Asset not found' });
  return res.json({ asset });
}));

router.post('/close-periods/:id/finalize', closer, withPeriod((period, req, res) => {
  res.json({ period: close.finalize(period, req.user.id, req.companyId, req.body || {}) });
}));

router.post('/close-periods/:id/reopen', closer, withPeriod((period, req, res) => {
  res.json({ period: close.reopen(period.id, req.user.id, req.companyId) });
}));

module.exports = router;
