<?php Session::init(); /*add*/?>
<?php

class Admin_Model extends Model
{
    public function __construct()
    {
        parent::__construct();
    }

    public function seguridad($token){
        
        try
        {
            $mesa = $this->db->prepare("SELECT * FROM token WHERE token = '".$token."' and estado = 'a'");
            $mesa->execute();
            $m = $mesa->fetchColumn();
            return $m;
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }

    }

    // bloqueoplataforma
    public function bloqueoplataforma($accion)
    {
        try
        {    

            $stm = $this->db->prepare("UPDATE tm_configuracion SET bloqueo = ? WHERE tm_configuracion.id_cfg = '1' ");
            $stm->execute(array($accion));

            if($stm){
                // Session::set('bloqueo_id', $data['tipo_bloqueo']); 
                return [
                    'success' => true,
                    'message' => ($accion==1) ? 'Se bloqueó el cliente exitosamente.' : 'Se desbloqueó el cliente exitosamente',
                ];
            }else{
                return [
                    'success' => false,
                    'message' => 'Error al ejecutar acción.',
                ];
            }
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }
    // fin bloqueoplataforma


    /* INICIO COMPROBANTE SIN ENVIAR SUNAT */

    public function datosEmpresa()
    {
        try
        {
            $ds = $this->db->prepare("SELECT bloqueo FROM tm_configuracion");
            $ds->execute();
            $data_s = $ds->fetch();

            //comprobantes sin enviar
            $stm = $this->db->prepare("SELECT COUNT(v.id_ven) AS sinenviar FROM v_ventas_con AS v INNER JOIN v_caja_aper AS c ON v.id_apc = c.id_apc INNER JOIN tm_tipo_doc AS d ON v.id_tdoc = d.id_tipo_doc WHERE v.ser_doc = d.serie AND v.id_tdoc <> 3 AND v.estado = 'a' AND (v.enviado_sunat = '' OR v.enviado_sunat = '0' OR v.enviado_sunat IS NULL)");
            $stm->execute();        
            $c = $stm->fetch(PDO::FETCH_OBJ);

            //comprobantes sin enviar
            $tdoc = $this->db->prepare("SELECT COUNT(v.id_ven) AS total_doc FROM v_ventas_con AS v INNER JOIN v_caja_aper AS c ON v.id_apc = c.id_apc INNER JOIN tm_tipo_doc AS d ON v.id_tdoc = d.id_tipo_doc WHERE v.ser_doc = d.serie AND v.id_tdoc <> 3 AND v.estado = 'a'");
            $tdoc->execute();        
            $tdoc_ = $tdoc->fetch(PDO::FETCH_OBJ);
            
            //notas de ventas
            $notv = $this->db->prepare("SELECT COUNT(v.id_ven) AS notas FROM v_ventas_con AS v INNER JOIN v_caja_aper AS c ON v.id_apc = c.id_apc INNER JOIN tm_tipo_doc AS d ON v.id_tdoc = d.id_tipo_doc WHERE v.ser_doc = d.serie AND v.id_tdoc = 3 AND v.estado = 'a'");
            $notv->execute();        
            $notv_ = $notv->fetch(PDO::FETCH_OBJ);

            //ultimo login
            $llog = $this->db->prepare("SELECT nombres, fecha_login FROM tm_usuario WHERE fecha_login IS NOT NULL ORDER BY fecha_login DESC LIMIT 1");
            $llog->execute();        
            $llog_ = $llog->fetch(PDO::FETCH_OBJ);

            $resultados = array('sinenviar' => $c->sinenviar, 'total_doc' => $tdoc_->total_doc, 'total_nv' => $notv_->notas, 'last_login' => $llog_);

            return $resultados;

        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    /* FIN COMPROBANTE SIN ENVIAR SUNAT */

    public function cron($data)
    {
        try 
        {
            Session::set('rol', '2');
            require_once 'controllers/PseController.php';
            $db = new Database(DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS, DB_CHARSET);
            $dsPendientesEnvio = $db->prepare("SELECT id_venta, id_tipo_doc, serie_doc, nro_doc, fecha_venta, total, comision_delivery, descuento_monto FROM tm_venta WHERE estado <> 'i' AND id_tipo_doc IN ('1','2') AND (enviado_sunat IS NULL OR enviado_sunat = '' OR enviado_sunat = '0') ORDER BY id_venta DESC");
            $dsPendientesEnvio->execute();
            $dataPendientesEnvio = $dsPendientesEnvio->fetchAll(PDO::FETCH_ASSOC);

            $dsPendientesBaja = $db->prepare("SELECT id_venta, id_tipo_doc, serie_doc, nro_doc, fecha_venta, total, comision_delivery, descuento_monto, enviado_sunat FROM tm_venta WHERE estado = 'i' AND id_tipo_doc IN ('1','2') AND enviado_sunat IN ('1','2') AND DATE(fecha_venta) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND (descripcion_sunat_cdr IS NULL OR descripcion_sunat_cdr = '' OR descripcion_sunat_cdr NOT LIKE '%ANULAD%') ORDER BY id_venta DESC");
            $dsPendientesBaja->execute();
            $dataPendientesBaja = $dsPendientesBaja->fetchAll(PDO::FETCH_ASSOC);

            $empresa = $db->query("SELECT ruc, client_id, client_secret FROM tm_empresa LIMIT 1")->fetch(PDO::FETCH_ASSOC);
            $stmMarcarAceptado = $db->prepare("UPDATE tm_venta SET enviado_sunat = 1, code_respuesta_sunat = '0', descripcion_sunat_cdr = 'ACEPTADO EN SUNAT (cron validador)', estado = 'a' WHERE id_venta = ?");
            $stmMarcarAnulado = $db->prepare("UPDATE tm_venta SET enviado_sunat = 1, code_respuesta_sunat = '0', descripcion_sunat_cdr = 'ANULADO EN SUNAT (cron validador)', estado = 'i' WHERE id_venta = ?");

            $obtenerTokenValidador = function ($empresaData) {
                if (!function_exists('curl_init')) {
                    return ['ok' => false, 'message' => 'cURL no disponible'];
                }
                if (empty($empresaData['client_id']) || empty($empresaData['client_secret'])) {
                    return ['ok' => false, 'message' => 'client_id/client_secret no configurados'];
                }

                $form_params = [
                    'grant_type' => 'client_credentials',
                    'scope' => 'https://api.sunat.gob.pe/v1/contribuyente/contribuyentes',
                    'client_id' => $empresaData['client_id'],
                    'client_secret' => $empresaData['client_secret'],
                ];

                $curl = curl_init();
                curl_setopt_array($curl, [
                    CURLOPT_URL => "https://api-seguridad.sunat.gob.pe/v1/clientesextranet/" . $empresaData['client_id'] . "/oauth2/token",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => http_build_query($form_params),
                    CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
                    CURLOPT_TIMEOUT => 20,
                ]);
                $response = curl_exec($curl);
                $httpCode = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
                $error = curl_error($curl);
                curl_close($curl);

                if ($response === false) {
                    return ['ok' => false, 'message' => 'Error token SUNAT: ' . $error];
                }
                $data = json_decode($response, true);
                if ($httpCode >= 400 || !is_array($data) || empty($data['access_token'])) {
                    return ['ok' => false, 'message' => 'No se pudo obtener token SUNAT'];
                }

                return ['ok' => true, 'token' => $data['access_token']];
            };

            $consultarEstadoSunat = function ($empresaData, $token, $venta) {
                if (!function_exists('curl_init')) {
                    return ['ok' => false, 'message' => 'cURL no disponible'];
                }

                $codComp = ((int) $venta['id_tipo_doc'] === 1) ? '03' : '01';
                $monto = (float) $venta['total'] + (float) $venta['comision_delivery'] - (float) $venta['descuento_monto'];
                $form_params = [
                    'numRuc' => $empresaData['ruc'],
                    'codComp' => $codComp,
                    'numeroSerie' => $venta['serie_doc'],
                    'numero' => $venta['nro_doc'],
                    'fechaEmision' => date('d/m/Y', strtotime($venta['fecha_venta'])),
                    'monto' => number_format($monto, 2, '.', '')
                ];

                $curl = curl_init();
                curl_setopt_array($curl, [
                    CURLOPT_URL => "https://api.sunat.gob.pe/v1/contribuyente/contribuyentes/" . $empresaData['ruc'] . "/validarcomprobante",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => json_encode($form_params),
                    CURLOPT_HTTPHEADER => [
                        "Authorization: Bearer " . $token,
                        'Content-Type: application/json'
                    ],
                    CURLOPT_TIMEOUT => 20,
                ]);
                $response = curl_exec($curl);
                $httpCode = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
                $error = curl_error($curl);
                curl_close($curl);

                if ($response === false) {
                    return ['ok' => false, 'message' => 'Error consulta SUNAT: ' . $error];
                }

                $res = json_decode($response, true);
                if ($httpCode >= 400 || !is_array($res)) {
                    return ['ok' => false, 'message' => 'Respuesta no valida del validador SUNAT'];
                }

                if (!empty($res['success'])) {
                    return ['ok' => true, 'estadoCp' => (string) ($res['data']['estadoCp'] ?? '')];
                }

                return ['ok' => false, 'message' => $res['message'] ?? 'SUNAT no pudo validar el comprobante'];
            };

            $resultado = [
                'ok' => true,
                'total_pendientes' => count($dataPendientesEnvio) + count($dataPendientesBaja),
                'total_pendientes_envio' => count($dataPendientesEnvio),
                'total_pendientes_baja' => count($dataPendientesBaja),
                'procesados' => 0,
                'aceptados_validador' => 0,
                'anulados_validador' => 0,
                'reintentos_envio' => 0,
                'reintentos_baja' => 0,
                'enviados_ok' => 0,
                'bajas_ok' => 0,
                'bajas_ticket' => 0,
                'errores' => 0,
                'detalle' => []
            ];
            if ((count($dataPendientesEnvio) + count($dataPendientesBaja)) > 0) {
                $pse = new PseController();
                $tokenValidador = null;
                if (!empty($empresa['ruc'])) {
                    $tokenResp = $obtenerTokenValidador($empresa);
                    if (!empty($tokenResp['ok'])) {
                        $tokenValidador = $tokenResp['token'];
                    } else {
                        $resultado['detalle'][] = ['mensaje' => 'Validador SUNAT no disponible: ' . $tokenResp['message']];
                    }
                }

                foreach($dataPendientesEnvio as $row):
                    $id_venta = (int) $row['id_venta'];
                    $id_tipo_doc = (int) $row['id_tipo_doc'];
                    $resultado['procesados']++;

                    try {
                        if (!empty($tokenValidador)) {
                            $validacion = $consultarEstadoSunat($empresa, $tokenValidador, $row);
                            if (!empty($validacion['ok']) && (string) $validacion['estadoCp'] === '1') {
                                $stmMarcarAceptado->execute([$id_venta]);
                                $resultado['aceptados_validador']++;
                                $resultado['detalle'][] = [
                                    'id_venta' => $id_venta,
                                    'id_tipo_doc' => $id_tipo_doc,
                                    'ok' => 1,
                                    'accion' => 'marcado_aceptado',
                                    'mensaje' => 'SUNAT reporta ACEPTADO'
                                ];
                                continue;
                            }
                        }

                        $resultado['reintentos_envio']++;
                        if ($id_tipo_doc === 1) {
                            $resp = $pse->resumenBoleta($id_venta, 1);
                        } else {
                            $resp = $pse->enviarFactura($id_venta);
                        }

                        if (is_array($resp) && !empty($resp['ok'])) {
                            $resultado['enviados_ok']++;
                        } else {
                            $resultado['errores']++;
                        }

                        $resultado['detalle'][] = [
                            'id_venta' => $id_venta,
                            'id_tipo_doc' => $id_tipo_doc,
                            'ok' => (is_array($resp) && !empty($resp['ok'])) ? 1 : 0,
                            'accion' => 'reintento_envio',
                            'mensaje' => is_array($resp) ? ($resp['mensaje'] ?? $resp['message'] ?? $resp['error'] ?? null) : 'Respuesta invalida'
                        ];
                    } catch (Throwable $e) {
                        $resultado['errores']++;
                        $resultado['detalle'][] = [
                            'id_venta' => $id_venta,
                            'id_tipo_doc' => $id_tipo_doc,
                            'ok' => 0,
                            'mensaje' => $e->getMessage()
                        ];
                    }
                endforeach;

                foreach($dataPendientesBaja as $row):
                    $id_venta = (int) $row['id_venta'];
                    $id_tipo_doc = (int) $row['id_tipo_doc'];
                    $resultado['procesados']++;

                    try {
                        if (!empty($tokenValidador)) {
                            $validacion = $consultarEstadoSunat($empresa, $tokenValidador, $row);
                            if (!empty($validacion['ok']) && (string) $validacion['estadoCp'] === '2') {
                                $stmMarcarAnulado->execute([$id_venta]);
                                $resultado['anulados_validador']++;
                                $resultado['detalle'][] = [
                                    'id_venta' => $id_venta,
                                    'id_tipo_doc' => $id_tipo_doc,
                                    'ok' => 1,
                                    'accion' => 'marcado_anulado',
                                    'mensaje' => 'SUNAT reporta ANULADO'
                                ];
                                continue;
                            }
                        }

                        $resultado['reintentos_baja']++;
                        if ($id_tipo_doc === 2) {
                            $resp = $pse->comunicacionBaja($id_venta);
                        } else {
                            $resp = $pse->resumenBoleta($id_venta, 3);
                        }

                        if (is_array($resp) && !empty($resp['ok'])) {
                            $esFinal = array_key_exists('final', $resp) ? ((bool) $resp['final']) : true;
                            if ($esFinal) {
                                $stmMarcarAnulado->execute([$id_venta]);
                                $resultado['bajas_ok']++;
                            } else {
                                $resultado['bajas_ticket']++;
                            }
                        } else {
                            $resultado['errores']++;
                        }

                        $resultado['detalle'][] = [
                            'id_venta' => $id_venta,
                            'id_tipo_doc' => $id_tipo_doc,
                            'ok' => (is_array($resp) && !empty($resp['ok'])) ? 1 : 0,
                            'accion' => 'reintento_baja',
                            'final' => is_array($resp) ? ($resp['final'] ?? null) : null,
                            'mensaje' => is_array($resp) ? ($resp['mensaje'] ?? $resp['message'] ?? $resp['error'] ?? null) : 'Respuesta invalida'
                        ];
                    } catch (Throwable $e) {
                        $resultado['errores']++;
                        $resultado['detalle'][] = [
                            'id_venta' => $id_venta,
                            'id_tipo_doc' => $id_tipo_doc,
                            'ok' => 0,
                            'accion' => 'reintento_baja',
                            'mensaje' => $e->getMessage()
                        ];
                    }
                endforeach;
            }else{
                $resultado['detalle'][] = ['mensaje' => 'No hay comprobantes pendientes por enviar/anular'];
            }

            return $resultado;
        }
        catch (Exception $e) 
        {
            return [
                'ok' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /* INICIO PEDIDOS PREPARADOS */

    public function contadorPedidosPreparados()
    {
        try
        {      
            if(Session::get('rol') == 1 OR Session::get('rol') == 2 OR Session::get('rol') == 3){
                $stm = $this->db->prepare("SELECT COUNT(id_pedido) AS cantidad FROM v_cocina_me WHERE id_tipo = 1 AND cantidad > 0 AND estado = 'c'");
                $stm->execute();   
            } elseif(Session::get('rol') == 5){
                $stm = $this->db->prepare("SELECT COUNT(id_pedido) AS cantidad FROM v_cocina_me WHERE id_tipo = 1 AND id_mozo = ? AND cantidad > 0 AND estado = 'c'");
                $stm->execute(array(Session::get('usuid')));   
            }
            $stm->execute();            
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            return $c;
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function listarPedidosPreparados()
    {
        try
        {      
            if(Session::get('rol') == 1 OR Session::get('rol') == 2 OR Session::get('rol') == 3){
                $stm = $this->db->prepare("SELECT * FROM v_cocina_me WHERE id_tipo = 1 AND cantidad > 0 AND estado = 'c'");
                $stm->execute();   
            } elseif(Session::get('rol') == 5){
                $stm = $this->db->prepare("SELECT * FROM v_cocina_me WHERE id_tipo = 1 AND id_mozo = ? AND cantidad > 0 AND estado = 'c'");
                $stm->execute(array(Session::get('usuid')));   
            } 
            $c = $stm->fetchAll(PDO::FETCH_OBJ);
            $data = array("data" => $c);
            $json = json_encode($data);
            echo $json;
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function pedidoEntregado($data)
    {
        try
        {   
            $sql = "UPDATE tm_detalle_pedido SET estado = 'd' WHERE id_pedido = ? AND id_pres = ? AND fecha_pedido = ?";
            $this->db->prepare($sql)
              ->execute(array(
                $data['id_pedido'],
                $data['id_pres'],
                $data['fecha_pedido']
                ));
        }
        catch(Exception $e)
        {
            die($e->getMessage());
        }
    }

    public function pedido_estado_update($data)
    {
        try 
        {
            if($data['estado']=='i'){$estado='p';}elseif($data['estado']=='p'){$estado='i';};
            $sql = "UPDATE tm_mesa SET estado = ? WHERE id_mesa = ?";
            $this->db->prepare($sql)->execute(array($estado,$data['id_mesa']));
        }
        catch (Exception $e) 
        {
            return false;
        }
    }

    /* FIN PEDIDOS PREPARADOS */


    /* FIN PEDIDOS PREPARADOS */

}

