<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');

$user = requireAuth();

switch ($tipo) {
    case 'getClientes':
        try {
            $page = max(1, intval($datapost['page'] ?? $_GET['page'] ?? 1));
            $limit = max(1, min(100, intval($datapost['limit'] ?? $_GET['limit'] ?? 20)));
            $offset = ($page - 1) * $limit;
            $q = trim($datapost['q'] ?? $_GET['q'] ?? '');

            $where = "WHERE c.activo = 1";
            $params = [];
            $types = "";

            if (!empty($q)) {
                $where .= " AND (c.nombre LIKE ? OR c.nombre_comercial LIKE ?)";
                $searchTerm = "%{$q}%";
                $params[] = $searchTerm;
                $params[] = $searchTerm;
                $types .= "ss";
            }

            // Contar total
            $countQuery = "SELECT COUNT(*) as total FROM clientes c $where";
            $countStmt = $conn->prepare($countQuery);
            if (!empty($params)) {
                $countStmt->bind_param($types, ...$params);
            }
            $countStmt->execute();
            $total = $countStmt->get_result()->fetch_assoc()['total'];

            // Obtener clientes paginados
            $query = "SELECT
                c.id,
                c.nombre,
                c.nombre_comercial,
                c.precio_venta,
                c.tiene_credito,
                c.monto_credito_maximo,
                c.dias_credito,
                c.saldo_credito_usado,
                c.fecha_creacion
            FROM clientes c
            $where
            ORDER BY c.nombre ASC
            LIMIT ? OFFSET ?";

            $params[] = $limit;
            $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($query);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $result = $stmt->get_result();

            $clientes = [];
            while ($row = $result->fetch_assoc()) {
                $cliente_id = intval($row['id']);

                // Teléfonos
                $telStmt = $conn->prepare("SELECT telefono, tipo, whatsapp FROM cliente_telefonos WHERE cliente_id = ? AND activo = 1 ORDER BY id ASC");
                $telStmt->bind_param("i", $cliente_id);
                $telStmt->execute();
                $telResult = $telStmt->get_result();
                $telefonos = [];
                while ($t = $telResult->fetch_assoc()) {
                    $telefonos[] = [
                        'telefono' => $t['telefono'],
                        'tipo' => $t['tipo'],
                        'whatsapp' => (bool)$t['whatsapp']
                    ];
                }

                // Direcciones
                $dirStmt = $conn->prepare("SELECT id, direccion, tipo, latitud, longitud FROM cliente_direcciones WHERE cliente_id = ? AND activo = 1 ORDER BY id ASC");
                $dirStmt->bind_param("i", $cliente_id);
                $dirStmt->execute();
                $dirResult = $dirStmt->get_result();
                $direcciones = [];
                while ($d = $dirResult->fetch_assoc()) {
                    $direcciones[] = [
                        'id' => intval($d['id']),
                        'direccion' => $d['direccion'],
                        'es_principal' => $d['tipo'] === 'principal',
                        'latitud' => $d['latitud'] ? floatval($d['latitud']) : null,
                        'longitud' => $d['longitud'] ? floatval($d['longitud']) : null
                    ];
                }

                $clientes[] = [
                    'id' => $cliente_id,
                    'nombre' => $row['nombre'],
                    'nombre_comercial' => $row['nombre_comercial'] ?? '',
                    'precio_venta' => $row['precio_venta'] ?? 'precio1',
                    'tiene_credito' => intval($row['tiene_credito'] ?? 0),
                    'monto_credito_maximo' => floatval($row['monto_credito_maximo'] ?? 0),
                    'dias_credito' => intval($row['dias_credito'] ?? 0),
                    'saldo_credito_usado' => floatval($row['saldo_credito_usado'] ?? 0),
                    'credito_disponible' => floatval(($row['monto_credito_maximo'] ?? 0) - ($row['saldo_credito_usado'] ?? 0)),
                    'telefonos' => $telefonos,
                    'direcciones' => $direcciones,
                    'fecha_creacion' => $row['fecha_creacion']
                ];
            }

            sendPaginatedResponse(true, "Clientes obtenidos", $clientes, $total, $page, $limit);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener clientes: " . $e->getMessage());
        }
        break;

    case 'getCliente':
        $id = intval($datapost['id'] ?? $_GET['id'] ?? 0);

        if ($id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        try {
            $query = "SELECT
                id, nombre, nombre_comercial, precio_venta, activo,
                tiene_credito, monto_credito_maximo, dias_credito, saldo_credito_usado,
                fecha_creacion, fecha_actualizacion
            FROM clientes WHERE id = ?";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($row = $result->fetch_assoc()) {
                $cliente_id = intval($row['id']);

                // Teléfonos
                $telStmt = $conn->prepare("SELECT id, telefono, tipo, whatsapp FROM cliente_telefonos WHERE cliente_id = ? AND activo = 1 ORDER BY id ASC");
                $telStmt->bind_param("i", $cliente_id);
                $telStmt->execute();
                $telefonos = [];
                while ($t = $telStmt->get_result()->fetch_assoc()) {
                    $telefonos[] = ['id' => intval($t['id']), 'telefono' => $t['telefono'], 'tipo' => $t['tipo'], 'whatsapp' => (bool)$t['whatsapp']];
                }

                // Direcciones
                $dirStmt = $conn->prepare("SELECT id, direccion, tipo, latitud, longitud FROM cliente_direcciones WHERE cliente_id = ? AND activo = 1 ORDER BY id ASC");
                $dirStmt->bind_param("i", $cliente_id);
                $dirStmt->execute();
                $direcciones = [];
                while ($d = $dirStmt->get_result()->fetch_assoc()) {
                    $direcciones[] = [
                        'id' => intval($d['id']),
                        'direccion' => $d['direccion'],
                        'es_principal' => $d['tipo'] === 'principal',
                        'latitud' => $d['latitud'] ? floatval($d['latitud']) : null,
                        'longitud' => $d['longitud'] ? floatval($d['longitud']) : null
                    ];
                }

                // Datos fiscales
                $datos_fiscales = [];
                $dfStmt = $conn->prepare("SELECT id, rfc, razon_social, regimen_fiscal, uso_cfdi, codigo_postal_fiscal, email_facturacion, es_principal FROM cliente_datos_fiscales WHERE cliente_id = ? AND activo = 1 ORDER BY es_principal DESC");
                if ($dfStmt) {
                    $dfStmt->bind_param("i", $cliente_id);
                    $dfStmt->execute();
                    while ($df = $dfStmt->get_result()->fetch_assoc()) {
                        $datos_fiscales[] = [
                            'id' => intval($df['id']),
                            'rfc' => $df['rfc'],
                            'razon_social' => $df['razon_social'],
                            'regimen_fiscal' => $df['regimen_fiscal'],
                            'uso_cfdi' => $df['uso_cfdi'] ?? '',
                            'codigo_postal_fiscal' => $df['codigo_postal_fiscal'],
                            'email_facturacion' => $df['email_facturacion'] ?? '',
                            'es_principal' => (bool)$df['es_principal']
                        ];
                    }
                }

                $cliente = [
                    'id' => $cliente_id,
                    'nombre' => $row['nombre'],
                    'nombre_comercial' => $row['nombre_comercial'] ?? '',
                    'precio_venta' => $row['precio_venta'] ?? 'precio1',
                    'activo' => intval($row['activo']),
                    'tiene_credito' => intval($row['tiene_credito'] ?? 0),
                    'monto_credito_maximo' => floatval($row['monto_credito_maximo'] ?? 0),
                    'dias_credito' => intval($row['dias_credito'] ?? 0),
                    'saldo_credito_usado' => floatval($row['saldo_credito_usado'] ?? 0),
                    'credito_disponible' => floatval(($row['monto_credito_maximo'] ?? 0) - ($row['saldo_credito_usado'] ?? 0)),
                    'telefonos' => $telefonos,
                    'direcciones' => $direcciones,
                    'datos_fiscales' => $datos_fiscales,
                    'fecha_creacion' => $row['fecha_creacion'],
                    'fecha_actualizacion' => $row['fecha_actualizacion']
                ];

                sendResponse(true, "Cliente obtenido exitosamente", $cliente);
            } else {
                sendResponse(false, "Cliente no encontrado");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener cliente: " . $e->getMessage());
        }
        break;

    case 'crearCliente':
        $nombre = trim($datapost['nombre'] ?? '');
        $nombre_comercial = trim($datapost['nombre_comercial'] ?? '');
        $precio_venta = trim($datapost['precio_venta'] ?? 'precio1');
        $tiene_credito = isset($datapost['tiene_credito']) ? intval($datapost['tiene_credito']) : 0;
        $monto_credito_maximo = floatval($datapost['monto_credito_maximo'] ?? 0);
        $dias_credito = intval($datapost['dias_credito'] ?? 0);
        $telefonos = $datapost['telefonos'] ?? [];
        $direcciones = $datapost['direcciones'] ?? [];

        if (empty($nombre)) {
            sendResponse(false, "El nombre es requerido");
        }

        if (empty($telefonos) || !is_array($telefonos)) {
            sendResponse(false, "Debe proporcionar al menos un teléfono");
        }

        foreach ($telefonos as $tel) {
            if (empty($tel['telefono']) || !preg_match('/^\d{10}$/', trim($tel['telefono']))) {
                sendResponse(false, "Todos los teléfonos deben tener 10 dígitos");
            }
        }

        try {
            $conn->begin_transaction();

            // Verificar teléfonos duplicados
            foreach ($telefonos as $tel) {
                $telefono = trim($tel['telefono']);
                $checkStmt = $conn->prepare("SELECT cliente_id FROM cliente_telefonos WHERE telefono = ? AND activo = 1");
                $checkStmt->bind_param("s", $telefono);
                $checkStmt->execute();
                if ($checkStmt->get_result()->num_rows > 0) {
                    $conn->rollback();
                    sendResponse(false, "Ya existe un cliente con el teléfono: $telefono");
                }
            }

            // Crear cliente
            $activo = 1;
            $stmt = $conn->prepare("INSERT INTO clientes (nombre, nombre_comercial, precio_venta, activo, tiene_credito, monto_credito_maximo, dias_credito) VALUES (?, ?, ?, ?, ?, ?, ?)");
            $stmt->bind_param("sssiidi", $nombre, $nombre_comercial, $precio_venta, $activo, $tiene_credito, $monto_credito_maximo, $dias_credito);

            if (!$stmt->execute()) {
                $conn->rollback();
                sendResponse(false, "Error al crear el cliente");
            }

            $cliente_id = $conn->insert_id;

            // Insertar teléfonos
            $telStmt = $conn->prepare("INSERT INTO cliente_telefonos (cliente_id, telefono, tipo, whatsapp, activo) VALUES (?, ?, ?, ?, 1)");
            foreach ($telefonos as $tel) {
                $telefono = trim($tel['telefono']);
                $tipo = $tel['tipo'] ?? 'principal';
                $whatsapp = isset($tel['whatsapp']) ? intval($tel['whatsapp']) : 0;
                $telStmt->bind_param("issi", $cliente_id, $telefono, $tipo, $whatsapp);
                if (!$telStmt->execute()) {
                    $conn->rollback();
                    sendResponse(false, "Error al guardar teléfono: $telefono");
                }
            }

            // Insertar direcciones
            if (!empty($direcciones) && is_array($direcciones)) {
                $dirStmt = $conn->prepare("INSERT INTO cliente_direcciones (cliente_id, direccion, tipo, latitud, longitud, activo) VALUES (?, ?, ?, ?, ?, 1)");
                foreach ($direcciones as $dir) {
                    $direccion = trim($dir['direccion'] ?? '');
                    if (!empty($direccion)) {
                        $tipo = ($dir['es_principal'] ?? false) ? 'principal' : 'otro';
                        $latitud = isset($dir['latitud']) ? floatval($dir['latitud']) : null;
                        $longitud = isset($dir['longitud']) ? floatval($dir['longitud']) : null;
                        $dirStmt->bind_param("issdd", $cliente_id, $direccion, $tipo, $latitud, $longitud);
                        if (!$dirStmt->execute()) {
                            $conn->rollback();
                            sendResponse(false, "Error al guardar dirección");
                        }
                    }
                }
            }

            $conn->commit();
            sendResponse(true, "Cliente creado exitosamente", ['id' => $cliente_id]);

        } catch (Exception $e) {
            $conn->rollback();
            sendResponse(false, "Error al crear cliente: " . $e->getMessage());
        }
        break;

    case 'actualizarCliente':
        $id = intval($datapost['id'] ?? 0);
        $nombre = trim($datapost['nombre'] ?? '');
        $nombre_comercial = trim($datapost['nombre_comercial'] ?? '');
        $precio_venta = trim($datapost['precio_venta'] ?? 'precio1');
        $tiene_credito = isset($datapost['tiene_credito']) ? intval($datapost['tiene_credito']) : 0;
        $monto_credito_maximo = floatval($datapost['monto_credito_maximo'] ?? 0);
        $dias_credito = intval($datapost['dias_credito'] ?? 0);

        if ($id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        if (empty($nombre)) {
            sendResponse(false, "El nombre es requerido");
        }

        try {
            // Verificar que existe
            $checkStmt = $conn->prepare("SELECT id FROM clientes WHERE id = ?");
            $checkStmt->bind_param("i", $id);
            $checkStmt->execute();
            if ($checkStmt->get_result()->num_rows === 0) {
                sendResponse(false, "Cliente no encontrado");
            }

            $activo = 1;
            $stmt = $conn->prepare("UPDATE clientes SET nombre = ?, nombre_comercial = ?, precio_venta = ?, activo = ?, tiene_credito = ?, monto_credito_maximo = ?, dias_credito = ? WHERE id = ?");
            $stmt->bind_param("sssiidii", $nombre, $nombre_comercial, $precio_venta, $activo, $tiene_credito, $monto_credito_maximo, $dias_credito, $id);

            if ($stmt->execute()) {
                sendResponse(true, "Cliente actualizado exitosamente");
            } else {
                sendResponse(false, "Error al actualizar el cliente");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al actualizar cliente: " . $e->getMessage());
        }
        break;

    case 'getCreditoCliente':
        $cliente_id = intval($datapost['cliente_id'] ?? $_GET['cliente_id'] ?? 0);

        if ($cliente_id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        try {
            $query = "SELECT tiene_credito, monto_credito_maximo, dias_credito, saldo_credito_usado
                     FROM clientes WHERE id = ? AND activo = 1";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $cliente_id);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($row = $result->fetch_assoc()) {
                sendResponse(true, "Crédito obtenido", [
                    'tiene_credito' => intval($row['tiene_credito']),
                    'monto_credito_maximo' => floatval($row['monto_credito_maximo']),
                    'dias_credito' => intval($row['dias_credito']),
                    'saldo_credito_usado' => floatval($row['saldo_credito_usado']),
                    'credito_disponible' => floatval($row['monto_credito_maximo'] - $row['saldo_credito_usado'])
                ]);
            } else {
                sendResponse(false, "Cliente no encontrado");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener crédito: " . $e->getMessage());
        }
        break;

    case 'getHistorialCliente':
        $cliente_id = intval($datapost['cliente_id'] ?? $_GET['cliente_id'] ?? 0);
        $page = max(1, intval($datapost['page'] ?? $_GET['page'] ?? 1));
        $limit = max(1, min(50, intval($datapost['limit'] ?? $_GET['limit'] ?? 10)));
        $offset = ($page - 1) * $limit;

        if ($cliente_id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        try {
            $countQuery = "SELECT COUNT(*) as total FROM ventas WHERE cliente_id = ?";
            $countStmt = $conn->prepare($countQuery);
            $countStmt->bind_param("i", $cliente_id);
            $countStmt->execute();
            $total = $countStmt->get_result()->fetch_assoc()['total'];

            $query = "SELECT id, folio, total, metodo_pago, estatus_pago, estado, tipo_entrega, fecha_creacion
                     FROM ventas
                     WHERE cliente_id = ?
                     ORDER BY fecha_creacion DESC
                     LIMIT ? OFFSET ?";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("iii", $cliente_id, $limit, $offset);
            $stmt->execute();
            $result = $stmt->get_result();

            $pedidos = [];
            while ($row = $result->fetch_assoc()) {
                $pedidos[] = [
                    'id' => intval($row['id']),
                    'folio' => $row['folio'],
                    'total' => floatval($row['total']),
                    'metodo_pago' => $row['metodo_pago'],
                    'estatus_pago' => $row['estatus_pago'],
                    'estado' => $row['estado'],
                    'tipo_entrega' => $row['tipo_entrega'],
                    'fecha_creacion' => $row['fecha_creacion']
                ];
            }

            sendPaginatedResponse(true, "Historial obtenido", $pedidos, $total, $page, $limit);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener historial: " . $e->getMessage());
        }
        break;

    case 'getVentasCliente':
        $cliente_id = intval($datapost['cliente_id'] ?? $_GET['cliente_id'] ?? 0);

        if ($cliente_id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        try {
            // Ventas con saldo pendiente (para cobros en ruta)
            $query = "SELECT id, folio, total, saldo_pendiente, metodo_pago, estatus_pago, fecha_creacion
                     FROM ventas
                     WHERE cliente_id = ? AND estatus_pago = 'pendiente' AND saldo_pendiente > 0 AND estado != 'cancelada'
                     ORDER BY fecha_creacion ASC";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $cliente_id);
            $stmt->execute();
            $result = $stmt->get_result();

            $ventas = [];
            $total_pendiente = 0;
            while ($row = $result->fetch_assoc()) {
                $saldo = floatval($row['saldo_pendiente']);
                $total_pendiente += $saldo;
                $ventas[] = [
                    'id' => intval($row['id']),
                    'folio' => $row['folio'],
                    'total' => floatval($row['total']),
                    'saldo_pendiente' => $saldo,
                    'metodo_pago' => $row['metodo_pago'],
                    'estatus_pago' => $row['estatus_pago'],
                    'fecha_creacion' => $row['fecha_creacion']
                ];
            }

            sendResponse(true, "Ventas pendientes obtenidas", [
                'ventas' => $ventas,
                'total_pendiente' => round($total_pendiente, 2),
                'cantidad_ventas' => count($ventas)
            ]);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener ventas: " . $e->getMessage());
        }
        break;

    case 'agregarDireccion':
        $cliente_id = intval($datapost['cliente_id'] ?? 0);
        $direccion = trim($datapost['direccion'] ?? '');
        $es_principal = isset($datapost['es_principal']) ? (bool)$datapost['es_principal'] : false;
        $latitud = isset($datapost['latitud']) ? floatval($datapost['latitud']) : null;
        $longitud = isset($datapost['longitud']) ? floatval($datapost['longitud']) : null;

        if ($cliente_id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        if (empty($direccion)) {
            sendResponse(false, "La dirección es requerida");
        }

        try {
            $tipo = $es_principal ? 'principal' : 'otro';
            $stmt = $conn->prepare("INSERT INTO cliente_direcciones (cliente_id, direccion, tipo, latitud, longitud, activo) VALUES (?, ?, ?, ?, ?, 1)");
            $stmt->bind_param("issdd", $cliente_id, $direccion, $tipo, $latitud, $longitud);

            if ($stmt->execute()) {
                sendResponse(true, "Dirección agregada exitosamente", ['id' => $conn->insert_id]);
            } else {
                sendResponse(false, "Error al agregar dirección");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al agregar dirección: " . $e->getMessage());
        }
        break;

    case 'actualizarDireccion':
        $id = intval($datapost['id'] ?? 0);
        $direccion = trim($datapost['direccion'] ?? '');
        $es_principal = isset($datapost['es_principal']) ? (bool)$datapost['es_principal'] : false;
        $latitud = isset($datapost['latitud']) ? floatval($datapost['latitud']) : null;
        $longitud = isset($datapost['longitud']) ? floatval($datapost['longitud']) : null;

        if ($id <= 0) {
            sendResponse(false, "ID de dirección requerido");
        }

        if (empty($direccion)) {
            sendResponse(false, "La dirección es requerida");
        }

        try {
            $tipo = $es_principal ? 'principal' : 'otro';
            $stmt = $conn->prepare("UPDATE cliente_direcciones SET direccion = ?, tipo = ?, latitud = ?, longitud = ? WHERE id = ?");
            $stmt->bind_param("ssddi", $direccion, $tipo, $latitud, $longitud, $id);

            if ($stmt->execute()) {
                sendResponse(true, "Dirección actualizada exitosamente");
            } else {
                sendResponse(false, "Error al actualizar dirección");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al actualizar dirección: " . $e->getMessage());
        }
        break;

    case 'agregarTelefono':
        $cliente_id = intval($datapost['cliente_id'] ?? 0);
        $telefono = trim($datapost['telefono'] ?? '');
        $tipo_tel = $datapost['tipo'] ?? 'otro';
        $whatsapp = isset($datapost['whatsapp']) ? intval($datapost['whatsapp']) : 0;

        if ($cliente_id <= 0) {
            sendResponse(false, "ID de cliente requerido");
        }

        if (empty($telefono) || !preg_match('/^\d{10}$/', $telefono)) {
            sendResponse(false, "El teléfono debe tener 10 dígitos");
        }

        try {
            // Verificar duplicado
            $checkStmt = $conn->prepare("SELECT id FROM cliente_telefonos WHERE telefono = ? AND activo = 1");
            $checkStmt->bind_param("s", $telefono);
            $checkStmt->execute();
            if ($checkStmt->get_result()->num_rows > 0) {
                sendResponse(false, "Ya existe un cliente con ese teléfono");
            }

            $stmt = $conn->prepare("INSERT INTO cliente_telefonos (cliente_id, telefono, tipo, whatsapp, activo) VALUES (?, ?, ?, ?, 1)");
            $stmt->bind_param("issi", $cliente_id, $telefono, $tipo_tel, $whatsapp);

            if ($stmt->execute()) {
                sendResponse(true, "Teléfono agregado exitosamente", ['id' => $conn->insert_id]);
            } else {
                sendResponse(false, "Error al agregar teléfono");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al agregar teléfono: " . $e->getMessage());
        }
        break;

    default:
        sendResponse(false, "Operación no válida para clientes");
        break;
}
