-- EL PANEL MANEJA LA NUMERACION DE LA IMPRENTA.
--
-- Las acciones nuevas del enrutador del panel para la pestaña Numeracion:
-- cargar los datos de la autorizacion, cargar los rangos que asigna el SENIAT,
-- repartirle un rango a un cliente, y ver como va cada quien.
--
-- Todo lo que se toca queda en el rastro del panel (fiscal.eventos_panel), que
-- solo agrega: quien cargo una providencia o le entrego numeros a un cliente
-- tiene que constar.

begin;

create or replace function public.fn_panel_imprenta(p_accion text, p_datos jsonb default '{}'::jsonb, p_quien text default null::text, p_desde text default null::text, p_yo text default null::text)
returns jsonb
language plpgsql
security definer
set search_path to 'public', 'fiscal'
as $function$
declare
  v jsonb;
  v_quien text := coalesce(nullif(btrim(p_quien), ''), 'sin identificar');
  v_viejo jsonb;
begin
  case p_accion
    -- ===== NUMERACION DE LA IMPRENTA (lo nuevo) =====
    when 'numeracion' then
      -- Todo lo que la imprenta necesita ver de un vistazo.
      select jsonb_build_object(
        'resumen', fiscal.resumen_numeracion(),
        'rangos', coalesce((select jsonb_agg(to_jsonb(r) order by r.desde)
                              from (select id, desde, hasta, oficio, asignado_en, anulado, nota,
                                           (hasta - desde + 1) as cuantos
                                      from fiscal.rangos_imprenta) r), '[]'::jsonb),
        'clientes', coalesce((select jsonb_agg(to_jsonb(t)) from fiscal.rangos_de_clientes() t), '[]'::jsonb)
      ) into v;
    when 'guardar_imprenta' then
      select fiscal.guardar_imprenta(
        p_datos->>'rif', p_datos->>'razon_social', p_datos->>'domicilio',
        p_datos->>'providencia', nullif(p_datos->>'providencia_fecha','')::date,
        nullif(p_datos->>'vigencia_hasta','')::date,
        coalesce((p_datos->>'autorizada')::boolean, false)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'imprenta_guardada',
        jsonb_build_object('providencia', p_datos->>'providencia',
                           'autorizada', coalesce((p_datos->>'autorizada')::boolean, false)));
    when 'cargar_rango' then
      select fiscal.cargar_rango_imprenta(
        (p_datos->>'desde')::bigint, (p_datos->>'hasta')::bigint,
        p_datos->>'oficio', p_datos->>'nota') into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'rango_cargado',
        jsonb_build_object('desde', p_datos->>'desde', 'hasta', p_datos->>'hasta',
                           'oficio', p_datos->>'oficio'));
    when 'entregar_rango' then
      select fiscal.entregar_rango(
        p_datos->>'rif', (p_datos->>'cuantos')::bigint,
        nullif(p_datos->>'rango_imprenta','')::uuid) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'rango_entregado',
        jsonb_build_object('rif', p_datos->>'rif', 'cuantos', p_datos->>'cuantos',
                           'desde', v->>'desde', 'hasta', v->>'hasta'));

    -- ===== LO QUE YA EXISTIA =====
    when 'entrar' then
      select to_jsonb(t) into v from fiscal.entrar_panel(
        p_datos->>'usuario', p_datos->>'clave', p_datos->>'desde') t;
    when 'tablero' then
      select to_jsonb(t) into v from fiscal.tablero() t;
    when 'clientes' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.clientes() t;
    when 'guardar_cliente' then
      select to_jsonb(fiscal.guardar_cliente(
        p_datos->>'rif', p_datos->>'razon_social', p_datos->>'domicilio',
        p_datos->>'representante', p_datos->>'cedula', p_datos->>'correo',
        p_datos->>'telefono', p_datos->>'sistema', coalesce(p_datos->>'serie', 'A'),
        coalesce((p_datos->>'rif_comprobado')::boolean, false), p_datos->>'nota')) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'cliente_guardado',
        jsonb_build_object('rif', p_datos->>'rif'));
    when 'activar_cliente' then
      select to_jsonb(fiscal.activar_cliente(p_datos->>'rif', (p_datos->>'activo')::boolean)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde,
        case when (p_datos->>'activo')::boolean then 'cliente_activado' else 'cliente_suspendido' end,
        jsonb_build_object('rif', p_datos->>'rif'));
    when 'llaves' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.llaves_de(p_datos->>'rif') t;
    when 'crear_llave' then
      select to_jsonb(fiscal.crear_llave(p_datos->>'rif', p_datos->>'nombre')) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'llave_creada',
        jsonb_build_object('rif', p_datos->>'rif', 'nombre', p_datos->>'nombre'));
    when 'revocar_llave' then
      select to_jsonb(fiscal.revocar_llave((p_datos->>'llave_id')::uuid)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'llave_revocada',
        jsonb_build_object('llave_id', p_datos->>'llave_id'));
    when 'relacion' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v
        from fiscal.relacion_mensual(p_datos->>'rif', (p_datos->>'anio')::int, (p_datos->>'mes')::int) t;
    when 'resumen' then
      select to_jsonb(t) into v from fiscal.resumen_mensual(
        p_datos->>'rif', (p_datos->>'anio')::int, (p_datos->>'mes')::int) t;
    when 'marcar_enviado' then
      select to_jsonb(fiscal.marcar_enviado(
        p_datos->>'rif', (p_datos->>'anio')::int, (p_datos->>'mes')::int,
        v_quien, p_datos->>'nota')) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'periodo_marcado_enviado',
        jsonb_build_object('rif', p_datos->>'rif', 'anio', p_datos->>'anio', 'mes', p_datos->>'mes'));
    when 'buscar_negocio' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v
        from fiscal.buscar_negocio(p_datos->>'texto') t;
    when 'vincular_negocio' then
      select to_jsonb(fiscal.vincular_negocio(
        (p_datos->>'restaurante_id')::uuid, p_datos->>'rif',
        coalesce(p_datos->>'serie', 'A'), v_quien)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'negocio_vinculado',
        jsonb_build_object('restaurante_id', p_datos->>'restaurante_id', 'rif', p_datos->>'rif'));
    when 'desvincular_negocio' then
      select to_jsonb(fiscal.desvincular_negocio((p_datos->>'restaurante_id')::uuid)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'negocio_desvinculado',
        jsonb_build_object('restaurante_id', p_datos->>'restaurante_id'));
    when 'negocios' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.negocios_gustito() t;
    when 'estaciones' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.estaciones_vivas() t;
    when 'cola' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.cola_por_revisar() t;
    when 'movimientos' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v
        from fiscal.movimientos_panel(coalesce((p_datos->>'limite')::int, 100)) t;
    when 'operadores' then
      select coalesce(jsonb_agg(to_jsonb(t)), '[]'::jsonb) into v from fiscal.operadores_lista() t;
    when 'guardar_operador' then
      select to_jsonb(fiscal.guardar_operador(
        p_datos->>'usuario', p_datos->>'nombre', p_datos->>'clave')) into v;
      perform fiscal.anotar_panel(v_quien, p_desde, 'operador_guardado',
        jsonb_build_object('usuario', lower(btrim(p_datos->>'usuario'))));
    when 'activar_operador' then
      select to_jsonb(fiscal.activar_operador(
        p_datos->>'usuario', (p_datos->>'activo')::boolean, p_yo)) into v;
      perform fiscal.anotar_panel(v_quien, p_desde,
        case when (p_datos->>'activo')::boolean then 'operador_activado' else 'operador_apagado' end,
        jsonb_build_object('usuario', lower(btrim(p_datos->>'usuario'))));
    else
      raise exception 'Accion desconocida';
  end case;
  return coalesce(v, 'null'::jsonb);
end;
$function$;

commit;
