-- =============================================================================
-- Отчет повременного учета работоспособности периферийного оборудования
-- Период: май 2026
-- Исключены устройства, начинающиеся на IRZ
-- Тип оборудования берется из инвентаризации Zabbix (поле type)
-- Координаты: широта + долгота из полей location_lat и location_lon
-- =============================================================================


WITH 
-- 1. Получаем все проверки ICMP за период
checks AS (
    SELECT 
        h.host AS host_name,
        COALESCE(h.name, h.host) AS visible_name,
        -- Тип оборудования из инвентаризации (поле type), если пусто - берем hardware
        COALESCE(hinv."name", 'не указан') AS equipment_type,
        -- Номер объекта ИТС РО (храним в поле notes инвентаризации)
        COALESCE(hinv.notes, '') AS object_number,
        -- Координаты: объединяем широту и долготу через пробел
        CASE 
            WHEN hinv.location_lat IS NOT NULL AND hinv.location_lon IS NOT NULL 
                 AND hinv.location_lat != '' AND hinv.location_lon != ''
            THEN hinv.location_lat || ' ' || hinv.location_lon
            WHEN hinv.location_lat IS NOT NULL AND hinv.location_lat != '' 
            THEN hinv.location_lat
            WHEN hinv.location_lon IS NOT NULL AND hinv.location_lon != '' 
            THEN hinv.location_lon
            ELSE ''
        END AS coordinates,
        -- Время проверки с учетом часового пояса
        TO_TIMESTAMP(hx.clock) AT TIME ZONE 'Europe/Moscow' AS ts,
        -- Статус: 1 = доступно, 0 = недоступно
        hx.value AS status
    FROM hosts h
    INNER JOIN items i 
        ON i.hostid = h.hostid 
        AND i.key_ = 'icmpping'
        AND i.status = 0
        AND i.value_type = 3  -- unsigned numeric
    INNER JOIN history_uint hx 
        ON hx.itemid = i.itemid
    LEFT JOIN host_inventory hinv 
        ON hinv.hostid = h.hostid
    WHERE 
        -- Только мониторимые хосты
        h.status = 0
        and h.host not like '%WiMAX'
        -- Исключаем оборудование, начинающееся на IRZ (любой регистр)
        -- AND UPPER(h.host) NOT LIKE 'IRZ%'
        -- Период: май 2026 года (измените под свои даты)
        --and hinv.notes = 'ОБЪЕКТ № 29'
        and CAST(nullif(regexp_replace(hinv.notes, 'ОБЪЕКТ №\s*', '', 'g'),'') as INTEGER) 
        --between 1 and 85
        in (1,2,4,5,8,9,11,12,14,24,25,27,28,29,30,31,32,34,35,36,38,40,41,42,43,44,45,46,48,49,50,51,53,54,55,57,58,60,62,63,64,65,66,67,68,69,70,76,77,81,82,84,85) 
        --AND hx.clock >= EXTRACT(EPOCH FROM TIMESTAMP '2026-06-01 00:00:00')
        --AND hx.clock < EXTRACT(EPOCH FROM TIMESTAMP '2026-06-05 00:00:00')
        AND TO_TIMESTAMP(hx.clock) >= to_date(${start_dt}, 'yyyymmdd') - interval '1 day'
        AND TO_TIMESTAMP(hx.clock) <= to_date(${end_dt}, 'yyyymmdd') + interval '1 day'  
        
),

-- 2. Добавляем предыдущий статус для определения моментов смены
checks_with_prev AS (
    SELECT 
        *,
        LAG(status) OVER (PARTITION BY host_name ORDER BY ts) AS prev_status,
        coalesce(lead(ts) OVER (PARTITION BY host_name ORDER BY ts), now()) AS next_ts
    FROM checks
),

 --3. Определяем моменты смены статуса (начало нового интервала)
status_changes AS (
    SELECT 
        host_name,
	    visible_name,
	    equipment_type,
	    object_number,
	    coordinates,
	    ts,
	    status, 
	    prev_status,
	    case 
		    when DATE(next_ts) > DATE(ts) then date_trunc('day', next_ts) + interval '00:00:00'
	    	else next_ts - interval '1 sec'
	    end as next_ts, 
        CASE WHEN status != prev_status THEN 1 
            ELSE 0 
        END AS is_start
    FROM checks_with_prev
    union all 
    SELECT
	    host_name,
	    visible_name,
	    equipment_type,
	    object_number,
	    coordinates,
	    date_trunc('day', next_ts) + interval '00:00:00' as ts,
	    status, 
	    prev_status,
	    next_ts - interval '1 sec' as next_ts,
	    1 as is_start
     FROM checks_with_prev
     where DATE(next_ts) > DATE(ts) 
),

-- 4. Нумеруем интервалы для каждого устройства
intervals AS (
    SELECT 
        *,
        SUM(is_start) OVER (PARTITION BY host_name ORDER BY ts) AS interval_id
    FROM status_changes
    WHERE status IS NOT null
    and date_trunc('day', ts) >= to_date(${start_dt}, 'yyyymmdd') and date_trunc('day', ts) <= to_date(${end_dt}, 'yyyymmdd')
),

-- 5. Агрегируем каждый непрерывный интервал
grouped_intervals AS (
    SELECT 
        host_name,
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        max(case when object_number similar to '%№%' then regexp_replace(object_number, 'ОБЪЕКТ №\s*', '', 'g')::int else null end) as object_num,
        MIN(ts) AS time_start,
        MAX(next_ts) AS time_end,
        MAX(status) AS status
    FROM intervals
    GROUP BY 
        host_name, 
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        interval_id
), 

-- 5_1. Определение маршрутизатора (заглушка)
router as 
(
	select  
		m.host_name,
        m.visible_name,
        m.equipment_type,
        v.object_number,
        v.coordinates,
        v.object_num,
        v.time_start,
        v.time_end,
        v.status
	from grouped_intervals v 
	join 
	(
		select host_name, visible_name, object_number, equipment_type, date_trunc('day', time_start) as time_start_dt
		from grouped_intervals 
		where equipment_type like 'Маршрутизатор%'
		group by 1,2,3,4,5
	) m on m.object_number = v.object_number 
	where v.equipment_type like 'Видеокамера%'
		and time_start_dt = date_trunc('day', v.time_start)
)

-- 6. Финальный вывод отчета
SELECT 
    ROW_NUMBER() OVER (order by object_num nulls last, equipment_type,time_start) AS "№ п/п",
    TO_CHAR(DATE(time_start), 'DD.MM.YYYY') AS "Дата",
    equipment_type as "Тип оборудования",
    case when object_num is null then 'на инвентаризации' else object_number end as "Номер_объекта_ИТС_РО",
    coordinates as "Координаты_расположения",
    TO_CHAR(time_start, 'HH24:MI:SS') AS "Время начала статуса",
    TO_CHAR(time_end, 'HH24:MI:SS') as "Время окончания статуса",
    CASE 
        WHEN status = 1 THEN 'доступно'
        ELSE 'недоступно'
    END AS "Статус"
FROM 
(
	select *  from grouped_intervals where equipment_type not like 'Маршрутизатор%'
	union all
	select * from router
) g 
ORDER BY 1
;