<?php

require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/database.php';
require_once '../../services/costs/CostAccess.php';
require_once '../../services/costs/CostManagementService.php';

require_login();
header('Content-Type: application/json; charset=utf-8');

if (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'POST') {
    http_response_code(405);
    echo json_encode(array('success' => false, 'message' => 'Método no permitido.'));
    exit;
}

try {
    csrf_require_valid_request();
    $action = trim((string)($_POST['action'] ?? ''));
    $service = new CostManagementService(db());
    $userId = current_user_id();
    $result = null;

    if ($action === 'save_entry') {
        cost_require('costs.edit');
        $payload = $_POST;
        $payload['allocations'] = $_POST['allocations_json'] ?? '[]';
        $result = $service->saveEntry($payload, $userId, cost_can('costs.approve'));
    } elseif ($action === 'void_entry') {
        cost_require('costs.edit');
        $service->voidEntry((int)($_POST['id'] ?? 0), $userId);
    } elseif ($action === 'save_category') {
        cost_require('costs.edit');
        $result = array('id' => $service->saveCategory($_POST, $userId));
    } elseif ($action === 'save_recurring') {
        cost_require('costs.edit');
        $result = array('id' => $service->saveRecurringRule($_POST, $userId));
    } elseif ($action === 'generate_recurring') {
        cost_require('costs.approve');
        $result = $service->generateRecurring($_POST['period'] ?? date('Y-m'), $userId);
    } elseif ($action === 'save_payroll') {
        cost_require('costs.payroll.edit');
        $result = $service->savePayroll($_POST, $userId);
    } elseif ($action === 'sync_dte') {
        cost_require('costs.approve');
        $result = $service->syncDteCosts($_POST['period'] ?? date('Y-m'), $userId);
    } elseif ($action === 'close_period' || $action === 'reopen_period') {
        cost_require('costs.close');
        $service->setPeriodClosed($_POST['period'] ?? date('Y-m'), $action === 'close_period', $_POST['notes'] ?? '', $userId);
    } else {
        throw new InvalidArgumentException('Acción de costos no reconocida.');
    }

    echo json_encode(array('success' => true, 'data' => $result), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (Throwable $e) {
    $status = http_response_code() === 403 ? 403 : ($e instanceof RuntimeException ? 409 : 400);
    http_response_code($status);
    if ($e instanceof PDOException) {
        error_log('costs action error: ' . $e->getMessage());
        $message = 'No fue posible guardar la información. Revisa datos duplicados o la instalación v8.8.';
    } else {
        $message = $e->getMessage();
    }
    echo json_encode(array('success' => false, 'message' => $message), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
