-- =====================================================
-- sp_TarjetaGestionar - SP UNIFICADO CON LOGGING
-- =====================================================

USE [Sis2000]
GO

IF OBJECT_ID('sp_TarjetaGestionar', 'P') IS NOT NULL
    DROP PROCEDURE sp_TarjetaGestionar;
GO

CREATE PROCEDURE sp_TarjetaGestionar
    -- Parámetros comunes
    @p_operacion VARCHAR(20),                    -- VALIDAR, CREAR, ELIMINAR
    @p_nro_tarjeta VARCHAR(8) = NULL,           -- Para VALIDAR, ELIMINAR
    @p_xcodigo_unico VARCHAR(8) = NULL,         -- Para VALIDAR, ELIMINAR
    @p_ctarlot INT = NULL,                      -- Para CREAR
    @p_cusuario VARCHAR(50),                    -- Requerido
    @p_xdireccion_ip VARCHAR(45) = NULL,        -- Opcional para logging
    
    -- Resultados (OUTPUT)
    @p_resultado VARCHAR(MAX) = NULL OUTPUT,     -- JSON con resultado
    @p_codigo_http INT = 200 OUTPUT             -- Código HTTP
AS
BEGIN
    SET NOCOUNT ON;
    
    DECLARE @v_datos_peticion VARCHAR(MAX);
    DECLARE @v_mensaje_error VARCHAR(MAX);
    DECLARE @v_ctarjeta INT;
    DECLARE @v_xcodigo VARCHAR(8);
    DECLARE @v_ccanal INT;
    DECLARE @v_tipo_accion VARCHAR(20);
    
    -- Construir JSON de petición
    DECLARE @v_json_base VARCHAR(MAX);
    DECLARE @v_json_nro VARCHAR(MAX) = '';
    DECLARE @v_json_codigo VARCHAR(MAX) = '';
    DECLARE @v_json_lote VARCHAR(MAX) = '';
    
    SET @v_json_base = '{"operacion":"' + @p_operacion + '"';
    
    IF @p_nro_tarjeta IS NOT NULL
        SET @v_json_nro = ',"nro_tarjeta":"' + @p_nro_tarjeta + '"';
    
    IF @p_xcodigo_unico IS NOT NULL
        SET @v_json_codigo = ',"codigo":"' + @p_xcodigo_unico + '"';
        
    IF @p_ctarlot IS NOT NULL
        SET @v_json_lote = ',"lote":' + CAST(@p_ctarlot AS VARCHAR);
    
    SET @v_datos_peticion = @v_json_base + @v_json_nro + @v_json_codigo + @v_json_lote + ',"usuario":"' + @p_cusuario + '"}';
    
    -- Validar operación
    IF @p_operacion NOT IN ('VALIDAR', 'CREAR', 'ELIMINAR') BEGIN
        SET @p_resultado = '{"status":"ERROR","message":"Operación no válida. Use: VALIDAR, CREAR, ELIMINAR"}';
        SET @p_codigo_http = 400;
        RETURN;
    END
    
    BEGIN TRY
        -- =====================================================
        -- OPERACIÓN: VALIDAR TARJETA
        -- =====================================================
        IF @p_operacion = 'VALIDAR' BEGIN
            SET @v_tipo_accion = 'VALIDAR_TARJETA';
            
            -- Validar parámetros requeridos
            IF @p_nro_tarjeta IS NULL AND @p_xcodigo_unico IS NULL BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"Para VALIDAR debe proporcionar nro_tarjeta o xcodigo_unico"}';
                SET @p_codigo_http = 400;
                RETURN;
            END
            
            -- Obtener datos de la tarjeta
            IF @p_nro_tarjeta IS NOT NULL BEGIN
                SELECT @v_ctarjeta = ctarjeta, @v_xcodigo = xcodigo_unico, @v_ccanal = L.ccanalalt 
                FROM tatarjeta T
                INNER JOIN tatarlot L ON L.ctarlot = T.ctarlot
                WHERE T.nro_tarjeta = @p_nro_tarjeta;
            END
            ELSE IF @p_xcodigo_unico IS NOT NULL BEGIN
                SELECT @v_ctarjeta = ctarjeta, @v_xcodigo = xcodigo_unico, @v_ccanal = L.ccanalalt 
                FROM tatarjeta T
                INNER JOIN tatarlot L ON L.ctarlot = T.ctarlot
                WHERE T.xcodigo_unico = @p_xcodigo_unico;
            END
            
            IF @v_ctarjeta IS NOT NULL BEGIN
                -- Tarjeta encontrada - devolver datos completos
                SELECT 
                    T.ctarjeta, T.xcodigo_unico, T.iestado as estado_tarjeta,
                    L.ctarlot, L.xnombre_lote, L.ccanalalt, L.cplan, L.fingreso,
                    C.xcanalalt, P.xdescripcion_l AS nombre_producto,
                    API.cci_rif, CL.xcliente as nombre_cliente, CL.itipopers,
                    (SELECT COUNT(*) FROM tatarjeta WHERE ctarlot = L.ctarlot) as total_tarjetas_lote,
                    CASE 
                        WHEN LTRIM(RTRIM(L.cplan)) = '1' THEN 'TRAVEL'
                        WHEN LTRIM(RTRIM(L.cplan)) = '56' THEN 'RC_VIDA'
                        WHEN LTRIM(RTRIM(L.cplan)) = '3' THEN 'TITULAR'
                        WHEN LTRIM(RTRIM(L.cplan)) = '5' THEN 'TITULAR'
                        ELSE 'TOMADOR'
                    END as tipo_formulario
                FROM tatarjeta T
                INNER JOIN tatarlot L ON L.ctarlot = T.ctarlot
                LEFT JOIN macanalalt C ON C.ccanalalt = L.ccanalalt
                LEFT JOIN maproductos P ON P.cproducto = L.cplan
                LEFT JOIN maclient_api API ON API.ccanalalt = L.ccanalalt
                LEFT JOIN maclient CL ON CL.cci_rif = API.cci_rif
                WHERE T.ctarjeta = @v_ctarjeta;
                
                -- Tarjeta encontrada - devolver datos completos
                DECLARE @v_respuesta_json VARCHAR(MAX);
                SET @v_respuesta_json = '{"status":"OK","message":"Tarjeta encontrada","codigo":"' + @v_xcodigo + '"}';
                
                SET @p_resultado = @v_respuesta_json;
                SET @p_codigo_http = 200;
                
                -- Registrar validación exitosa
                DECLARE @v_respuesta_validar VARCHAR(MAX);
                SET @v_respuesta_validar = @p_resultado;
                
                EXEC sp_TarjetaRegistrarLogProceso 
                    @p_ctarjeta = @v_ctarjeta,
                    @p_xcodigo_tarjeta = @v_xcodigo,
                    @p_ccanal = @v_ccanal,
                    @p_itipo_accion = @v_tipo_accion,
                    @p_xestado_proceso = 'EXITOSO',
                    @p_xendpoint_api = 'sp_TarjetaGestionar',
                    @p_xdatos_peticion = @v_datos_peticion,
                    @p_xdatos_respuesta = @v_respuesta_validar,
                    @p_xmensaje_error = NULL,
                    @p_ncodigo_http = @p_codigo_http,
                    @p_xdireccion_ip = @p_xdireccion_ip;
            END
            ELSE BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"Tarjeta no encontrada"}';
                SET @p_codigo_http = 404;
                
                -- Registrar error de validación
                DECLARE @v_respuesta_error_validar VARCHAR(MAX);
                SET @v_respuesta_error_validar = @p_resultado;
                
                DECLARE @v_codigo_tarjeta_error VARCHAR(8);
                SET @v_codigo_tarjeta_error = ISNULL(@p_xcodigo_unico, @p_nro_tarjeta);
                
                EXEC sp_TarjetaRegistrarLogProceso 
                    @p_ctarjeta = NULL,
                    @p_xcodigo_tarjeta = @v_codigo_tarjeta_error,
                    @p_ccanal = NULL,
                    @p_itipo_accion = @v_tipo_accion,
                    @p_xestado_proceso = 'ERROR',
                    @p_xendpoint_api = 'sp_TarjetaGestionar',
                    @p_xdatos_peticion = @v_datos_peticion,
                    @p_xdatos_respuesta = @v_respuesta_error_validar,
                    @p_xmensaje_error = 'Tarjeta no encontrada',
                    @p_ncodigo_http = @p_codigo_http,
                    @p_xdireccion_ip = @p_xdireccion_ip;
            END
        END
        
        -- =====================================================
        -- OPERACIÓN: CREAR TARJETA INDIVIDUAL
        -- =====================================================
        ELSE IF @p_operacion = 'CREAR' BEGIN
            SET @v_tipo_accion = 'CREAR_TARJETA';
            
            -- Validar parámetros requeridos
            IF @p_ctarlot IS NULL BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"Para CREAR debe proporcionar ctarlot"}';
                SET @p_codigo_http = 400;
                RETURN;
            END
            
            -- Verificar que el lote existe
            IF NOT EXISTS (SELECT 1 FROM tatarlot WHERE ctarlot = @p_ctarlot) BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"El lote especificado no existe"}';
                SET @p_codigo_http = 404;
                RETURN;
            END
            
            -- Obtener canal del lote
            SELECT @v_ccanal = ccanalalt FROM tatarlot WHERE ctarlot = @p_ctarlot;
            
            -- Generar tarjeta única
            DECLARE @v_nro_nuevo VARCHAR(8), @v_codigo_nuevo VARCHAR(8);
            DECLARE @v_chars_code VARCHAR(60) = '0123456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ';
            DECLARE @v_exists BIT = 1;
            
            -- Generar Nro Tarjeta único
            WHILE @v_exists = 1 BEGIN
                SET @v_nro_nuevo = RIGHT('00000000' + CAST(ABS(CHECKSUM(NEWID())) % 100000000 AS VARCHAR(8)), 8);
                IF NOT EXISTS (SELECT 1 FROM tatarjeta WHERE nro_tarjeta = @v_nro_nuevo) SET @v_exists = 0;
            END
            
            -- Generar Código Único
            SET @v_exists = 1;
            WHILE @v_exists = 1 BEGIN
                SET @v_codigo_nuevo = '';
                DECLARE @k INT = 0;
                WHILE @k < 8 BEGIN
                    SET @v_codigo_nuevo = @v_codigo_nuevo + SUBSTRING(@v_chars_code, CAST((ABS(CHECKSUM(NEWID())) % LEN(@v_chars_code)) + 1 AS INT), 1);
                    SET @k = @k + 1;
                END
                IF NOT EXISTS (SELECT 1 FROM tatarjeta WHERE xcodigo_unico = @v_codigo_nuevo) SET @v_exists = 0;
            END
            
            -- Insertar tarjeta
            INSERT INTO tatarjeta (nro_tarjeta, xcodigo_unico, ctarlot, iestado, fingreso, cusuario)
            VALUES (@v_nro_nuevo, @v_codigo_nuevo, @p_ctarlot, 1, GETDATE(), @p_cusuario);
            
            SET @v_ctarjeta = SCOPE_IDENTITY();
            SET @v_xcodigo = @v_codigo_nuevo;
            
            DECLARE @v_respuesta_crear VARCHAR(MAX);
            SET @v_respuesta_crear = '{"status":"OK","message":"Tarjeta creada correctamente","id_tarjeta":' + CAST(@v_ctarjeta AS VARCHAR) + ',"nro_tarjeta":"' + @v_nro_nuevo + '","codigo":"' + @v_codigo_nuevo + '"}';
            
            SET @p_resultado = @v_respuesta_crear;
            SET @p_codigo_http = 200;
            
            -- Registrar creación exitosa
            EXEC sp_TarjetaRegistrarLogProceso 
                @p_ctarjeta = @v_ctarjeta,
                @p_xcodigo_tarjeta = @v_codigo_nuevo,
                @p_ccanal = @v_ccanal,
                @p_itipo_accion = @v_tipo_accion,
                @p_xestado_proceso = 'EXITOSO',
                @p_xendpoint_api = 'sp_TarjetaGestionar',
                @p_xdatos_peticion = @v_datos_peticion,
                @p_xdatos_respuesta = @p_resultado,
                @p_xmensaje_error = NULL,
                @p_ncodigo_http = @p_codigo_http,
                @p_xdireccion_ip = @p_xdireccion_ip;
            
            -- Devolver datos de la tarjeta creada
            SELECT @v_ctarjeta AS id_tarjeta_creada, @v_nro_nuevo AS nro_tarjeta, @v_codigo_nuevo AS codigo_unico;
        END
        
        -- =====================================================
        -- OPERACIÓN: ELIMINAR TARJETA (SOFT DELETE)
        -- =====================================================
        ELSE IF @p_operacion = 'ELIMINAR' BEGIN
            SET @v_tipo_accion = 'ELIMINAR_TARJETA';
            
            -- Validar parámetros requeridos
            IF @p_nro_tarjeta IS NULL BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"Para ELIMINAR debe proporcionar nro_tarjeta"}';
                SET @p_codigo_http = 400;
                RETURN;
            END
            
            -- Obtener datos de la tarjeta
            SELECT @v_ctarjeta = ctarjeta, @v_xcodigo = xcodigo_unico, @v_ccanal = L.ccanalalt 
            FROM tatarjeta T
            INNER JOIN tatarlot L ON L.ctarlot = T.ctarlot
            WHERE T.nro_tarjeta = @p_nro_tarjeta;
            
            IF @v_ctarjeta IS NOT NULL BEGIN
                -- Soft delete: cambiar estado a 99 (eliminado)
                UPDATE tatarjeta SET iestado = 99, fultmod = GETDATE(), cusuariomod = @p_cusuario
                WHERE ctarjeta = @v_ctarjeta;
                
                DECLARE @v_respuesta_eliminar VARCHAR(MAX);
                SET @v_respuesta_eliminar = '{"status":"OK","message":"Tarjeta eliminada correctamente","tarjeta":"' + @v_xcodigo + '"}';
                
                SET @p_resultado = @v_respuesta_eliminar;
                SET @p_codigo_http = 200;
                
                -- Registrar eliminación
                EXEC sp_TarjetaRegistrarLogProceso 
                    @p_ctarjeta = @v_ctarjeta,
                    @p_xcodigo_tarjeta = @v_xcodigo,
                    @p_ccanal = @v_ccanal,
                    @p_itipo_accion = @v_tipo_accion,
                    @p_xestado_proceso = 'EXITOSO',
                    @p_xendpoint_api = 'sp_TarjetaGestionar',
                    @p_xdatos_peticion = @v_datos_peticion,
                    @p_xdatos_respuesta = @v_respuesta_eliminar,
                    @p_xmensaje_error = NULL,
                    @p_ncodigo_http = @p_codigo_http,
                    @p_xdireccion_ip = @p_xdireccion_ip;
                
                SELECT 'OK' AS Status, 'Tarjeta eliminada correctamente' AS Message;
            END
            ELSE BEGIN
                SET @p_resultado = '{"status":"ERROR","message":"Tarjeta no encontrada"}';
                SET @p_codigo_http = 404;
                
                -- Registrar error
                EXEC sp_TarjetaRegistrarLogProceso 
                    @p_ctarjeta = NULL,
                    @p_xcodigo_tarjeta = NULL,
                    @p_ccanal = NULL,
                    @p_itipo_accion = @v_tipo_accion,
                    @p_xestado_proceso = 'ERROR',
                    @p_xendpoint_api = 'sp_TarjetaGestionar',
                    @p_xdatos_peticion = @v_datos_peticion,
                    @p_xdatos_respuesta = @p_resultado,
                    @p_xmensaje_error = 'Tarjeta no encontrada',
                    @p_ncodigo_http = @p_codigo_http,
                    @p_xdireccion_ip = @p_xdireccion_ip;
                
                RAISERROR('Tarjeta no encontrada', 16, 1);
            END
        END
        
    END TRY
    BEGIN CATCH
        SET @v_mensaje_error = ERROR_MESSAGE();
        SET @p_codigo_http = 500;
        
        DECLARE @v_respuesta_error_catch VARCHAR(MAX);
        SET @v_respuesta_error_catch = '{"status":"ERROR","message":"' + REPLACE(@v_mensaje_error, '"', '''') + '"}';
        
        SET @p_resultado = @v_respuesta_error_catch;
        
        -- Variables locales para el manejo de error
        DECLARE @v_ctarjeta_error INT = @v_ctarjeta;
        DECLARE @v_xcodigo_error VARCHAR(8) = @v_xcodigo;
        DECLARE @v_ccanal_error INT = @v_ccanal;
        DECLARE @v_tipo_accion_error VARCHAR(20) = @v_tipo_accion;
        
        -- Registrar error inesperado
        EXEC sp_TarjetaRegistrarLogProceso 
            @p_ctarjeta = @v_ctarjeta_error,
            @p_xcodigo_tarjeta = @v_xcodigo_error,
            @p_ccanal = @v_ccanal_error,
            @p_itipo_accion = @v_tipo_accion_error,
            @p_xestado_proceso = 'ERROR',
            @p_xendpoint_api = 'sp_TarjetaGestionar',
            @p_xdatos_peticion = @v_datos_peticion,
            @p_xdatos_respuesta = @v_respuesta_error_catch,
            @p_xmensaje_error = @v_mensaje_error,
            @p_ncodigo_http = @p_codigo_http,
            @p_xdireccion_ip = @p_xdireccion_ip;
        
        THROW;
    END CATCH
END
GO

PRINT '=== sp_TarjetaGestionar creado correctamente ===';
GO
