<?php
/**
 * Actualiza un cliente existente.
 * P1: delega edicion, normalizacion de RUT, duplicados y sincronizacion snapshot a CustomerService.
 */
require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/permissions.php';
require_once '../../services/crm/CustomerService.php';
require_once '../../services/crm/CrmService.php';
require_once '../../services/crm/RestockForecastService.php';

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: /modules/customers/');
    exit;
}

$id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
if ($id <= 0) {
    die('ID de cliente inválido.');
}

try {
    $legalName = trim((string)($_POST['legal_name'] ?? ($_POST['customer_name'] ?? '')));
    $commercialName = trim((string)($_POST['commercial_name'] ?? ''));

    $businessActivity = trim((string)($_POST['business_activity'] ?? ''));
    if ($businessActivity === '') {
        throw new RuntimeException('Debe ingresar el giro o actividad económica del cliente.');
    }

    $customerService = new CustomerService();
    $current = $customerService->requireActiveById($id, 'Cliente no encontrado o desactivado.');
    if ($commercialName === '') {
        $commercialName = trim((string)($current['commercial_name'] ?? ''));
    }
    if ($commercialName === '') {
        $commercialName = $legalName;
    }
    $payload = array(
        'customer_name' => $commercialName,
        'commercial_name' => $commercialName,
        'legal_name' => $legalName,
        'customer_tax_id' => $_POST['customer_tax_id'] ?? '',
        'contact_name' => $_POST['contact_name'] ?? '',
        'email' => $_POST['email'] ?? '',
        'phone' => $_POST['phone'] ?? '',
        'address' => $_POST['address'] ?? '',
        'district' => $_POST['district'] ?? '',
        'city' => $_POST['city'] ?? '',
        'region' => $_POST['region'] ?? '',
        'website' => $_POST['website'] ?? '',
        'payment_terms' => $_POST['payment_terms'] ?? 'contado',
        'default_income_center_id' => $_POST['default_income_center_id'] ?? null,
        'default_cost_center_id' => $_POST['default_cost_center_id'] ?? null,
        'supplier_default_cost_center_id' => $_POST['supplier_default_cost_center_id'] ?? ($current['supplier_default_cost_center_id'] ?? ($_POST['default_cost_center_id'] ?? null)),
        'supplier_payment_terms_id' => $_POST['supplier_payment_terms_id'] ?? ($current['supplier_payment_terms_id'] ?? null),
        'counterparty_type' => $_POST['counterparty_type'] ?? ($current['counterparty_type'] ?? 'customer'),
        'is_supplier' => array_key_exists('is_supplier', $_POST) ? $_POST['is_supplier'] : ($current['is_supplier'] ?? 0),
        'supplier_status' => $_POST['supplier_status'] ?? ($current['supplier_status'] ?? 'inactive'),
        'business_activity' => $businessActivity,
        'country' => $_POST['country'] ?? 'Chile',
        'latitude' => $_POST['latitude'] ?? '',
        'longitude' => $_POST['longitude'] ?? '',
        'geocode_status' => $_POST['geocode_status'] ?? '',
        'geocode_source' => $_POST['geocode_source'] ?? '',
        'geocode_query' => $_POST['geocode_query'] ?? ''
    );

    if (array_key_exists('restock_days', $_POST)) {
        $payload['restock_days'] = $_POST['restock_days'];
    }

    $updatedCustomer = $customerService->update($id, $payload);

    // El ciclo manual pasa a ser el valor vigente. La fecha se proyecta
    // exclusivamente desde la última compra emitida; nunca desde la fecha actual.
    if (array_key_exists('restock_days', $payload)) {
        try {
            $restockService = new RestockForecastService(db());
            if ((int)$payload['restock_days'] > 0) {
                $crm = new CrmService();
                $crm->projectCustomerRestockDate($id, $updatedCustomer['customer_tax_id'] ?? '');
                $restockService->refreshFromCustomer($id, null, 'manual_cycle_update');
            } else {
                $restockService->cancelCustomerForecasts($id, 'Ciclo manual eliminado por usuario.');
            }
        } catch (Throwable $projectionError) {
            // El valor manual queda guardado. Sin una compra válida la fecha
            // permanece vacía y una indisponibilidad FACTO no revierte la edición.
            error_log('Restock customer update ' . $id . ': ' . $projectionError->getMessage());
        }
    }

    header('Location: /modules/customers/view.php?id=' . $id . '&updated=1');
    exit;
} catch (Throwable $e) {
    die($e->getMessage());
}
