WITH 
-- 1. Получаем все проверки ICMP за период
checks AS (
    SELECT 
        h.host AS host_name,
        COALESCE(h.name, h.host) AS visible_name,
        COALESCE(hinv."name", 'не указан') AS equipment_type,
        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 check_time,
        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
    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'
        AND CAST(NULLIF(REGEXP_REPLACE(hinv.notes, 'ОБЪЕКТ №\s*', '', 'g'), '') AS INTEGER) 
            BETWEEN 1 AND 85
        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 check_time) AS prev_status,
        COALESCE(LEAD(check_time) OVER (PARTITION BY host_name ORDER BY check_time), NOW()) AS next_check_time
    FROM checks
),

-- 3. Определяем моменты смены статуса
status_changes AS (
    SELECT 
        host_name,
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        check_time,
        status, 
        prev_status,
        CASE 
            WHEN DATE(next_check_time) > DATE(check_time) 
                THEN DATE_TRUNC('day', check_time) + INTERVAL '1 day'
            ELSE next_check_time 
        END AS next_check_time, 
        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_check_time) + INTERVAL '00:00:00' AS check_time,
        status, 
        prev_status,
        next_check_time, 
        1 AS is_start
    FROM checks_with_prev
    WHERE DATE(next_check_time) > DATE(check_time)
),

-- 4. Нумеруем интервалы
intervals AS (
    SELECT 
        *,
        SUM(is_start) OVER (PARTITION BY host_name ORDER BY check_time) AS interval_id
    FROM status_changes
    WHERE status IS NOT NULL
        AND DATE_TRUNC('day', check_time) >= TO_DATE(${start_dt}, 'yyyymmdd') 
        AND DATE_TRUNC('day', check_time) <= TO_DATE(${end_dt}, 'yyyymmdd')
),

-- 5. Группируем интервалы
grouped_intervals AS (
    SELECT 
        host_name,
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        MIN(check_time) AS check_time,
        MAX(next_check_time) AS next_check_time,
        MAX(status) AS status
    FROM intervals
    GROUP BY 
        host_name, 
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        interval_id
),

-- 6. Посуточная агрегация (часы доступности)
daily_stats_raw AS (
    SELECT 
        host_name,
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        DATE(check_time) AS check_date,
        ROUND(
            SUM(CASE WHEN status = 1 THEN EXTRACT(EPOCH FROM (next_check_time - check_time)) / 3600 ELSE 0 END) * 2
        ) / 2 AS available_hours
    FROM grouped_intervals
    GROUP BY 
        host_name,
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        DATE(check_time)
),

-- 7. Статистика по периферии (для маршрутизаторов)
peripheral_stats AS (
    SELECT 
        object_number,
        check_date,
        MAX(CASE WHEN available_hours > 12 THEN 1 ELSE 0 END) AS has_peripheral_work
    FROM daily_stats_raw
    WHERE equipment_type NOT LIKE 'Маршрутизатор%'
    GROUP BY object_number, check_date
),

-- 8. Собираем все дни месяца
all_dates AS (
    SELECT generate_series(
        TO_DATE(${start_dt}, 'yyyymmdd'),
        TO_DATE(${end_dt}, 'yyyymmdd'),
        '1 day'::interval
    )::date AS check_date
),

-- 9. Кросс-джойн для каждого оборудования
equipment_dates AS (
    SELECT DISTINCT
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        ad.check_date
    FROM daily_stats_raw d
    CROSS JOIN all_dates ad
),

-- 10. Присоединяем доступность ко всем дням
daily_stats_full AS (
    SELECT 
        ed.visible_name,
        ed.equipment_type,
        ed.object_number,
        ed.coordinates,
        ed.check_date,
        COALESCE(dsr.available_hours, 0) AS available_hours
    FROM equipment_dates ed
    LEFT JOIN daily_stats_raw dsr 
        ON dsr.visible_name = ed.visible_name
        AND dsr.check_date = ed.check_date
),

-- 11. Финальная агрегация по оборудованию
equipment_summary AS (
    SELECT 
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        STRING_AGG(
            CASE 
                WHEN available_hours > 0 THEN TO_CHAR(check_date, 'DD.MM') || ':' || available_hours::TEXT
                ELSE NULL
            END,
            '; ' ORDER BY check_date
        ) AS daily_schedule,
        COUNT(CASE WHEN available_hours > 12 THEN 1 END) AS days_gt_12h,
        COUNT(CASE WHEN available_hours <= 12 AND available_hours > 0 THEN 1 END) AS days_le_12h,
        ROUND(AVG(available_hours), 3) AS avg_hours,
        -- Суммарные сутки доступности (факт) - по каждому устройству
        ROUND(SUM(available_hours) / 24, 0) AS total_days_per_device
    FROM daily_stats_full
    GROUP BY 
        visible_name,
        equipment_type,
        object_number,
        coordinates
),

-- 12. Отдельно считаем работу маршрутизаторов
router_work AS (
    SELECT 
        d.object_number,
        COUNT(DISTINCT d.check_date) AS router_work_days
    FROM daily_stats_raw d
    INNER JOIN peripheral_stats p 
        ON p.object_number = d.object_number 
        AND p.check_date = d.check_date
    WHERE d.equipment_type LIKE 'Маршрутизатор%'
        AND p.has_peripheral_work = 1
    GROUP BY d.object_number
),

-- 13. Определяем этап
stages AS (
    SELECT DISTINCT
        object_number,
        CASE 
            WHEN object_number IN ('4','28','30','31','34','36','40','42','55','57','58','62','63','64','67','68','69','76','81','82','85') THEN '1 этап'
            WHEN object_number IN ('1','9','12','27','35','38','41','43','44','48','49','51','53','54','60','65','77','84') THEN '2 этап'
            ELSE '3 этап'
        END AS stage
    FROM equipment_summary
),

-- 14. Подготавливаем данные для PIVOT-агрегации
daily_pivot AS (
    SELECT 
        visible_name,
        equipment_type,
        object_number,
        coordinates,
        check_date,
        available_hours
    FROM daily_stats_full
),

-- 15. СВОДНАЯ ТАБЛИЦА по типам оборудования
summary_by_type AS (
    SELECT 
        equipment_type,
        -- оборудование-сутки факт (сумма по всем устройствам типа)
        ROUND(SUM(total_days_per_device), 0) AS fact_days,
        -- Кол-во оборудования (статичное из Excel)
        CASE 
            WHEN equipment_type LIKE 'Видеокамера%' THEN 85
            WHEN equipment_type LIKE 'Детектор%' THEN 79
            WHEN equipment_type LIKE 'Метеостанция%' THEN 30
            WHEN equipment_type LIKE 'Маршрутизатор%' THEN 88
            WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 88
            WHEN equipment_type LIKE 'Криптошлюз%' THEN 88
            ELSE 0
        END AS equipment_count,
        -- оборудование-сутки план = 30 дней × количество оборудования
        CASE 
            WHEN equipment_type LIKE 'Видеокамера%' THEN 30 * 85
            WHEN equipment_type LIKE 'Детектор%' THEN 30 * 79
            WHEN equipment_type LIKE 'Метеостанция%' THEN 30 * 30
            WHEN equipment_type LIKE 'Маршрутизатор%' THEN 30 * 88
            WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 30 * 88
            WHEN equipment_type LIKE 'Криптошлюз%' THEN 30 * 88
            ELSE 0
        END AS plan_days,
        -- оборудование-сутки процент = факт / план
        ROUND(SUM(total_days_per_device) / 
            CASE 
                WHEN equipment_type LIKE 'Видеокамера%' THEN 30 * 85
                WHEN equipment_type LIKE 'Детектор%' THEN 30 * 79
                WHEN equipment_type LIKE 'Метеостанция%' THEN 30 * 30
                WHEN equipment_type LIKE 'Маршрутизатор%' THEN 30 * 88
                WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 30 * 88
                WHEN equipment_type LIKE 'Криптошлюз%' THEN 30 * 88
                ELSE 1
            END, 9) AS percent,
        -- Тариф в сутки (статичный из Excel)
        CASE 
            WHEN equipment_type LIKE 'Видеокамера%' THEN 43038.15
            WHEN equipment_type LIKE 'Детектор%' THEN 91293.59
            WHEN equipment_type LIKE 'Метеостанция%' THEN 53323.20
            WHEN equipment_type LIKE 'Маршрутизатор%' THEN 8868.36
            WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 4514.60
            WHEN equipment_type LIKE 'Криптошлюз%' THEN 10883.72
            ELSE 0
        END AS daily_rate,
        -- Итоговая сумма = Тариф × Кол-во дней в месяце × процент
        ROUND(
            CASE 
                WHEN equipment_type LIKE 'Видеокамера%' THEN 43038.15
                WHEN equipment_type LIKE 'Детектор%' THEN 91293.59
                WHEN equipment_type LIKE 'Метеостанция%' THEN 53323.20
                WHEN equipment_type LIKE 'Маршрутизатор%' THEN 8868.36
                WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 4514.60
                WHEN equipment_type LIKE 'Криптошлюз%' THEN 10883.72
                ELSE 0
            END * 30 * 
            (SUM(total_days_per_device) / 
                CASE 
                    WHEN equipment_type LIKE 'Видеокамера%' THEN 30 * 85
                    WHEN equipment_type LIKE 'Детектор%' THEN 30 * 79
                    WHEN equipment_type LIKE 'Метеостанция%' THEN 30 * 30
                    WHEN equipment_type LIKE 'Маршрутизатор%' THEN 30 * 88
                    WHEN equipment_type LIKE 'Коммутационный шкаф%' THEN 30 * 88
                    WHEN equipment_type LIKE 'Криптошлюз%' THEN 30 * 88
                    ELSE 1
                END),
            2
        ) AS total_amount
    FROM equipment_summary
    GROUP BY equipment_type
)

-- 16. Итоговый SELECT (детальный отчёт)
SELECT 
    'ДЕТАЛЬНЫЙ ОТЧЁТ' AS section,
    s.stage AS "Этап",
    s.object_number AS "№ объекта",
    e.equipment_type AS "Вид оборудования",
    e.coordinates AS "Координаты",
    MAX(CASE WHEN d.check_date = DATE '2026-06-01' THEN d.available_hours END) AS "01.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-02' THEN d.available_hours END) AS "02.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-03' THEN d.available_hours END) AS "03.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-04' THEN d.available_hours END) AS "04.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-05' THEN d.available_hours END) AS "05.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-06' THEN d.available_hours END) AS "06.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-07' THEN d.available_hours END) AS "07.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-08' THEN d.available_hours END) AS "08.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-09' THEN d.available_hours END) AS "09.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-10' THEN d.available_hours END) AS "10.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-11' THEN d.available_hours END) AS "11.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-12' THEN d.available_hours END) AS "12.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-13' THEN d.available_hours END) AS "13.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-14' THEN d.available_hours END) AS "14.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-15' THEN d.available_hours END) AS "15.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-16' THEN d.available_hours END) AS "16.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-17' THEN d.available_hours END) AS "17.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-18' THEN d.available_hours END) AS "18.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-19' THEN d.available_hours END) AS "19.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-20' THEN d.available_hours END) AS "20.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-21' THEN d.available_hours END) AS "21.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-22' THEN d.available_hours END) AS "22.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-23' THEN d.available_hours END) AS "23.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-24' THEN d.available_hours END) AS "24.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-25' THEN d.available_hours END) AS "25.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-26' THEN d.available_hours END) AS "26.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-27' THEN d.available_hours END) AS "27.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-28' THEN d.available_hours END) AS "28.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-29' THEN d.available_hours END) AS "29.06",
    MAX(CASE WHEN d.check_date = DATE '2026-06-30' THEN d.available_hours END) AS "30.06",
    e.days_gt_12h AS "Дней >12 ч",
    e.days_le_12h AS "Дней ≤12 ч",
    e.avg_hours AS "Среднее часов",
    COALESCE(rw.router_work_days, 0) AS "Маршрутизатор работа в днях"
FROM equipment_summary e
LEFT JOIN stages s ON s.object_number = e.object_number
LEFT JOIN daily_pivot d 
    ON d.visible_name = e.visible_name 
    AND d.equipment_type = e.equipment_type
    AND d.object_number = e.object_number
    AND d.coordinates = e.coordinates
LEFT JOIN router_work rw ON rw.object_number = e.object_number
WHERE e.daily_schedule IS NOT NULL
GROUP BY 
    s.stage,
    s.object_number,
    e.equipment_type,
    e.coordinates,
    e.days_gt_12h,
    e.days_le_12h,
    e.avg_hours,
    rw.router_work_days

UNION ALL

-- 17. СВОДНАЯ ТАБЛИЦА (как в Excel)
SELECT 
    'СВОДНАЯ' AS section,
    '' AS "Этап",
    '' AS "№ объекта",
    s.equipment_type AS "Вид оборудования",
    '' AS "Координаты",
    NULL AS "01.06",
    NULL AS "02.06",
    NULL AS "03.06",
    NULL AS "04.06",
    NULL AS "05.06",
    NULL AS "06.06",
    NULL AS "07.06",
    NULL AS "08.06",
    NULL AS "09.06",
    NULL AS "10.06",
    NULL AS "11.06",
    NULL AS "12.06",
    NULL AS "13.06",
    NULL AS "14.06",
    NULL AS "15.06",
    NULL AS "16.06",
    NULL AS "17.06",
    NULL AS "18.06",
    NULL AS "19.06",
    NULL AS "20.06",
    NULL AS "21.06",
    NULL AS "22.06",
    NULL AS "23.06",
    NULL AS "24.06",
    NULL AS "25.06",
    NULL AS "26.06",
    NULL AS "27.06",
    NULL AS "28.06",
    NULL AS "29.06",
    NULL AS "30.06",
    -- Колонки сводной таблицы в правильном порядке
    s.fact_days AS "оборудование-сутки факт",
    s.plan_days AS "оборудование-сутки план",
    s.percent AS "оборудование-сутки процент",
    s.equipment_count AS "Кол-во оборудования",
    s.daily_rate AS "Тариф в сутки по договору ИТСР",
    s.total_amount AS "Итоговая сумма к начислению"
FROM summary_by_type s

UNION ALL

-- 18. ИТОГОВАЯ СТРОКА
SELECT 
    'ИТОГО' AS section,
    '' AS "Этап",
    '' AS "№ объекта",
    'Итоговая Сумма' AS "Вид оборудования",
    '' AS "Координаты",
    NULL AS "01.06",
    NULL AS "02.06",
    NULL AS "03.06",
    NULL AS "04.06",
    NULL AS "05.06",
    NULL AS "06.06",
    NULL AS "07.06",
    NULL AS "08.06",
    NULL AS "09.06",
    NULL AS "10.06",
    NULL AS "11.06",
    NULL AS "12.06",
    NULL AS "13.06",
    NULL AS "14.06",
    NULL AS "15.06",
    NULL AS "16.06",
    NULL AS "17.06",
    NULL AS "18.06",
    NULL AS "19.06",
    NULL AS "20.06",
    NULL AS "21.06",
    NULL AS "22.06",
    NULL AS "23.06",
    NULL AS "24.06",
    NULL AS "25.06",
    NULL AS "26.06",
    NULL AS "27.06",
    NULL AS "28.06",
    NULL AS "29.06",
    NULL AS "30.06",
    SUM(s.fact_days) AS "оборудование-сутки факт",
    SUM(s.plan_days) AS "оборудование-сутки план",
    ROUND(SUM(s.fact_days) / SUM(s.plan_days), 9) AS "оборудование-сутки процент",
    SUM(s.equipment_count) AS "Кол-во оборудования",
    NULL AS "Тариф в сутки по договору ИТСР",
    SUM(s.total_amount) AS "Итоговая сумма к начислению"
FROM summary_by_type s

ORDER BY section DESC, "Этап", "№ объекта", "Вид оборудования";