<?php

require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/permissions.php';
require_once '../../core/database.php';
require_once '../../services/crm/OpportunityAccessService.php';
require_once '../../services/crm/OpportunityStageHistoryService.php';

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(array('success' => false, 'error' => 'Método no permitido.'), JSON_UNESCAPED_UNICODE);
    exit;
}
csrf_require_valid_request();

$id = (int)($_POST['id'] ?? 0);
$action = trim((string)($_POST['hold_action'] ?? 'hold'));
$reason = trim((string)($_POST['reason'] ?? ''));
$until = trim((string)($_POST['until'] ?? ''));

try {
    if ($id <= 0) throw new InvalidArgumentException('ID de oportunidad inválido.');
    if (!in_array($action, array('hold','release'), true)) throw new InvalidArgumentException('Acción inválida.');
    if ($action === 'hold' && $reason === '') throw new InvalidArgumentException('Debes indicar por qué se excluye del archivo automático.');
    if ($until !== '' && (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $until) || $until < date('Y-m-d'))) {
        throw new InvalidArgumentException('La fecha de revisión no es válida.');
    }

    $pdo = db();
    $stmt = $pdo->prepare("SELECT * FROM crm_opportunities WHERE id=? AND deleted_at IS NULL LIMIT 1");
    $stmt->execute(array($id));
    $old = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$old) throw new RuntimeException('Oportunidad no encontrada.');
    OpportunityAccessService::assertCanManage($old, current_user() ?: array(), 'administrar el archivo de');
    if (!empty($old['archived_at'])) throw new InvalidArgumentException('La oportunidad ya está archivada.');
    if (($old['stage'] ?? '') !== 'facturada') throw new InvalidArgumentException('Solo las oportunidades facturadas pueden excluirse del archivo mensual.');

    $pdo->beginTransaction();
    if ($action === 'hold') {
        $update = $pdo->prepare("UPDATE crm_opportunities SET archive_hold_reason=?, archive_exempt_until=?, updated_at=NOW() WHERE id=? AND archived_at IS NULL");
        $update->execute(array($reason, $until !== '' ? $until : null, $id));
    } else {
        $update = $pdo->prepare("UPDATE crm_opportunities SET archive_hold_reason=NULL, archive_exempt_until=NULL, updated_at=NOW() WHERE id=? AND archived_at IS NULL");
        $update->execute(array($id));
    }

    $user = current_user() ?: array();
    $userId = !empty($user['id']) ? (int)$user['id'] : null;
    $userName = trim((string)($user['name'] ?? $user['email'] ?? 'Sistema'));
    $activity = $pdo->prepare("INSERT INTO crm_activities (opportunity_id, customer_id, customer_name, activity_type, title, description, owner_name, activity_date) VALUES (?, ?, ?, 'cambio_estado', ?, ?, ?, NOW())");
    $title = $action === 'hold' ? 'Archivo mensual pausado' : 'Archivo mensual reactivado';
    $description = $action === 'hold'
        ? 'Motivo: ' . $reason . ($until !== '' ? "\nRevisar hasta: " . $until : '')
        : 'La oportunidad vuelve a ser elegible para archivo automático al cierre del mes.';
    $activity->execute(array($id, $old['customer_id'] ?? null, $old['customer_name'] ?? null, $title, $description, $userName));
    OpportunityStageHistoryService::lifecycle(
        $pdo,
        $id,
        $action === 'hold' ? 'archive_hold' : 'archive_hold_release',
        array('archive_hold_reason' => $old['archive_hold_reason'] ?? null, 'archive_exempt_until' => $old['archive_exempt_until'] ?? null),
        array('archive_hold_reason' => $action === 'hold' ? $reason : null, 'archive_exempt_until' => $action === 'hold' && $until !== '' ? $until : null),
        $userId,
        $userName,
        'manual'
    );
    $pdo->commit();

    echo json_encode(array('success' => true, 'held' => $action === 'hold'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (OpportunityAuthorizationException $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    http_response_code(403);
    echo json_encode(array('success' => false, 'error' => $e->getMessage()), JSON_UNESCAPED_UNICODE);
} catch (InvalidArgumentException $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    http_response_code(422);
    echo json_encode(array('success' => false, 'error' => $e->getMessage()), JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    error_log('opportunity archive hold failed: ' . $e->getMessage());
    http_response_code(500);
    echo json_encode(array('success' => false, 'error' => 'No fue posible actualizar la exclusión de archivo.'), JSON_UNESCAPED_UNICODE);
}
