<?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/CrmService.php';
require_once '../../services/crm/CustomerService.php';
require_once '../../services/crm/TimelineAuditService.php';
require_once '../../services/crm/PaymentStatusService.php';
require_once '../../core/notifications.php';

require_login();
require_permission('module.crm');

$sessionUser = current_user();
$currentUser = !empty($sessionUser['name']) ? $sessionUser['name'] : (!empty($sessionUser['email']) ? $sessionUser['email'] : 'Sistema');

$pdo = db();
$customerService = new CustomerService($pdo);
$timelineAudit = new TimelineAuditService($pdo);

$id = isset($_POST['id']) ? (int) $_POST['id'] : 0;

if ($id <= 0) die('ID inválido.');

$stmt = $pdo->prepare("SELECT * FROM crm_opportunities WHERE id = ? AND deleted_at IS NULL LIMIT 1");
$stmt->execute(array($id));
$old = $stmt->fetch();

if (!$old) die('Oportunidad no encontrada.');

$customerId = isset($_POST['customer_id']) ? (int) $_POST['customer_id'] : 0;
$customer = $customerService->findActiveById($customerId);

$title = isset($_POST['title']) ? trim($_POST['title']) : '';
$stage = isset($_POST['stage']) ? trim($_POST['stage']) : '';
$expectedValue = isset($_POST['expected_value']) ? (float) $_POST['expected_value'] : 0;
$probability = isset($_POST['probability']) ? (int) $_POST['probability'] : 20;
$ownerName = isset($_POST['owner_name']) ? trim($_POST['owner_name']) : '';
$ownerUserId = isset($_POST['owner_user_id']) && $_POST['owner_user_id'] !== '' ? (int) $_POST['owner_user_id'] : null; // AGREGADO
$source = isset($_POST['source']) ? trim($_POST['source']) : '';
$competitor = isset($_POST['competitor']) ? trim($_POST['competitor']) : '';
$expectedCloseDate = isset($_POST['expected_close_date']) && $_POST['expected_close_date'] !== '' ? $_POST['expected_close_date'] : null;
$nextAction = isset($_POST['next_action']) ? trim($_POST['next_action']) : '';
$nextActionDate = isset($_POST['next_action_date']) && $_POST['next_action_date'] !== '' ? $_POST['next_action_date'] : null;
$notes = isset($_POST['notes']) ? trim($_POST['notes']) : '';
$paymentStatus = isset($_POST['payment_status']) ? trim($_POST['payment_status']) : 'no_facturado';
$paymentDueDate = isset($_POST['payment_due_date']) && $_POST['payment_due_date'] !== '' ? $_POST['payment_due_date'] : null;
$paymentPaidDate = isset($_POST['payment_paid_date']) && $_POST['payment_paid_date'] !== '' ? $_POST['payment_paid_date'] : null;

$errors = array();

if (!$customer) $errors['customer_id'] = 'Debe seleccionar un cliente válido.';
if ($title === '') $errors['title'] = 'Debe ingresar un título de oportunidad.';
if ($stage === '') $errors['stage'] = 'Debe seleccionar una etapa.';
if ($source === '') $errors['source'] = 'Debe seleccionar un origen.';
if ($expectedCloseDate === null) $errors['expected_close_date'] = 'Debe indicar una fecha estimada de cierre.';
if ($nextAction === '') $errors['next_action'] = 'Debe seleccionar una próxima acción.';
if ($nextActionDate === null) $errors['next_action_date'] = 'Debe indicar una fecha para la próxima acción.';

if (!empty($errors)) {
    if (isset($_POST['ajax']) && $_POST['ajax'] === '1') {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'errors' => $errors]);
        exit;
    }
    $_SESSION['form_errors'] = $errors;
    $_SESSION['form_old'] = $_POST;
    header('Location: /modules/crm/opportunity_edit.php?id=' . $id);
    exit;
}

$billingAdjustment = PaymentStatusService::applyFacturadaRules(array(
    'stage' => $stage,
    'old_stage' => $old['stage'] ?? '',
    'payment_status' => $paymentStatus,
    'payment_due_date' => $paymentDueDate,
    'payment_paid_date' => $paymentPaidDate,
    'payment_terms' => $customer['payment_terms'] ?? ($customer['facto_payment_term'] ?? 'contado'),
    'base_date' => date('Y-m-d'),
));
$paymentStatus = $billingAdjustment['payment_status'];
$paymentDueDate = $billingAdjustment['payment_due_date'];
$paymentPaidDate = $billingAdjustment['payment_paid_date'];
$billingChanges = $billingAdjustment['changes'];

// AGREGADO owner_user_id al UPDATE
$stmt = $pdo->prepare("
    UPDATE crm_opportunities
    SET customer_id = ?, title = ?, customer_name = ?, customer_tax_id = ?, stage = ?, payment_status = ?, 
        payment_due_date = ?, payment_paid_date = ?, expected_value = ?, probability = ?, owner_name = ?, 
        owner_user_id = ?, source = ?, competitor = ?, expected_close_date = ?, next_action = ?, next_action_date = ?, 
        notes = ?, updated_at = CURRENT_TIMESTAMP
    WHERE id = ?
");

$stmt->execute(array(
    $customerId, $title, $customer['customer_name'], $customer['customer_tax_id'], $stage, $paymentStatus, 
    $paymentDueDate, $paymentPaidDate, $expectedValue, $probability, $ownerName, $ownerUserId, $source, 
    $competitor, $expectedCloseDate, $nextAction, $nextActionDate, $notes, $id
));

$newOpportunityForAudit = array(
    'customer_id' => $customerId,
    'customer_name' => $customer['customer_name'],
    'customer_tax_id' => $customer['customer_tax_id'],
    'title' => $title,
    'stage' => $stage,
    'payment_status' => $paymentStatus,
    'payment_due_date' => $paymentDueDate,
    'payment_paid_date' => $paymentPaidDate,
    'expected_value' => $expectedValue,
    'probability' => $probability,
    'owner_name' => $ownerName,
    'owner_user_id' => $ownerUserId,
    'source' => $source,
    'competitor' => $competitor,
    'expected_close_date' => $expectedCloseDate,
    'next_action' => $nextAction,
    'next_action_date' => $nextActionDate,
    'notes' => $notes,
);

$changes = $timelineAudit->buildOpportunityUpdateChanges($old, $newOpportunityForAudit);
if (!empty($billingChanges)) {
    $changes = array_merge($changes, $billingChanges);
}

// Motor Predictivo
if ($stage === 'facturada' && $old['stage'] !== 'facturada') {
    try {
        $crm = new CrmService();
        $restockData = $crm->updateCustomerRestockFrequency($customerId, $customer['customer_tax_id']);
        if (!$restockData || empty($restockData['next_restock_date'])) {
            throw new RuntimeException('No hay documentos suficientes para calcular un ciclo de reposicion confiable.');
        }

        $restockDays = $restockData['restock_days'];
        $nextDateStr = $restockData['next_restock_date'];
        $mesProximo = date('m/Y', strtotime($nextDateStr));
        $tituloFuturo = "Reposicion Programada - " . $mesProximo;

        $stmtAuto = $pdo->prepare("
            INSERT INTO crm_opportunities
            (customer_id, title, customer_name, customer_tax_id, stage, expected_value, probability, owner_name, expected_close_date)
            VALUES (?, ?, ?, ?, 'nuevo', ?, 50, ?, ?)
        ");
        $stmtAuto->execute(array($customerId, $tituloFuturo, $customer['customer_name'], $customer['customer_tax_id'], $expectedValue, $ownerName, $nextDateStr));

        $changes[] = "Motor predictivo: ciclo ajustado a $restockDays dias. Reposicion creada para el $nextDateStr.";
    } catch (Exception $e) {
        $changes[] = "Motor predictivo: no fue posible proyectar recompra al facturar (" . $e->getMessage() . ").";
    }
}

$newActivityHtml = '';
// Registro limpio de cambios reales
if (!empty($changes)) {
    $desc = implode("\n", $changes);
    $timelineAudit->insertActivity(
        $id,
        $customerId,
        $customer['customer_name'],
        'sistema',
        'Oportunidad actualizada',
        $changes,
        $currentUser,
        ''
    );

    // Construir el HTML de la nueva actividad para inyectarlo en vivo
    $newActivityHtml = '
    <div class="crm-timeline-item" style="animation: fadeIn 0.5s ease-in-out;">
        <span class="crm-timeline-dot sistema"></span>
        <div>
            <strong>Oportunidad actualizada</strong>
            <p class="text-secondary text-sm" style="margin-top: 4px;">' . nl2br(htmlspecialchars($desc)) . '</p>
            <span class="text-muted text-sm" style="margin-top: 4px; display: block;">Justo ahora &middot; ' . htmlspecialchars($currentUser) . '</span>
        </div>
    </div>';
}


// ==========================================================================
// NOTIFICACIONES TRANSVERSALES CRM
// ==========================================================================
$opportunityUrl = '/modules/crm/opportunity.php?id=' . $id;
$oldOwnerUserId = !empty($old['owner_user_id']) ? (int)$old['owner_user_id'] : null;
$oldStage = (string)($old['stage'] ?? '');
$oldPaymentStatus = (string)($old['payment_status'] ?? 'no_facturado');

notify_high_value_opportunity_event(
    $id,
    $title,
    $customer['customer_name'],
    (float)$expectedValue,
    $ownerUserId,
    array('dedupe_key' => 'opportunity.high_value:' . $id)
);

if ($ownerUserId && $ownerUserId !== $oldOwnerUserId) {
    notify_crm_user_event(
        'opportunity.assigned',
        $ownerUserId,
        'Oportunidad asignada: ' . $title,
        'Cliente: ' . $customer['customer_name'] . "\nEtapa: " . $stage . ($expectedValue > 0 ? "\nValor esperado: " . number_format($expectedValue, 0, ',', '.') : ''),
        $opportunityUrl,
        'opportunity',
        $id,
        array('dedupe_key' => 'opportunity.assigned:' . $id . ':' . $ownerUserId)
    );
}

if ($stage === 'facturada' && $oldStage !== 'facturada') {
    notify_crm_owner_or_admin_event(
        'opportunity.facturada',
        $ownerUserId,
        'Oportunidad facturada: ' . $title,
        'Cliente: ' . $customer['customer_name'] . "\nCobranza: " . $paymentStatus . ($paymentDueDate ? "\nVencimiento: " . $paymentDueDate : ''),
        $opportunityUrl,
        'opportunity',
        $id,
        array('dedupe_key' => 'opportunity.facturada:' . $id)
    );
}

if ($paymentStatus !== $oldPaymentStatus && in_array($paymentStatus, array('por_cobrar', 'atrasado', 'pagado'), true)) {
    $billingEvent = $paymentStatus === 'pagado' ? 'billing.paid' : ($paymentStatus === 'atrasado' ? 'billing.overdue' : 'billing.por_cobrar');
    $billingTitle = $paymentStatus === 'pagado' ? 'Cobranza pagada' : ($paymentStatus === 'atrasado' ? 'Cobranza atrasada' : 'Cobranza por cobrar');
    notify_crm_owner_or_admin_event(
        $billingEvent,
        $ownerUserId,
        $billingTitle . ': ' . $title,
        'Cliente: ' . $customer['customer_name'] . "\nEstado anterior: " . $oldPaymentStatus . "\nEstado actual: " . $paymentStatus . ($paymentDueDate ? "\nVencimiento: " . $paymentDueDate : '') . ($paymentPaidDate ? "\nFecha de pago: " . $paymentPaidDate : ''),
        $opportunityUrl,
        'opportunity',
        $id,
        array('dedupe_key' => $billingEvent . ':' . $id . ':' . ($paymentDueDate ?: $paymentPaidDate ?: date('Y-m-d')))
    );
}

// ==========================================================================
// INTEGRACION CALENDARIO (INTERNO + GOOGLE)
// ==========================================================================
if ($ownerUserId) {
    require_once '../../services/crm/CrmCalendarService.php';
    try {
        $calendar = new CrmCalendarService($ownerUserId);
        $calendar->syncOpportunity($id, $customer['customer_name'], $title, $_POST);
    } catch (Exception $e) {
        error_log("Error Calendar Update: " . $e->getMessage());
    }
}
if (isset($_POST['ajax']) && $_POST['ajax'] === '1') {
    header('Content-Type: application/json');
    echo json_encode([
        'success' => true,
        'new_activity_html' => $newActivityHtml
    ]);
    exit;
}

header('Location: /modules/crm/opportunity.php?id=' . $id);
exit;
exit;
exit;