const express = require("express");
const router = express.Router();
const { query } = require("../mods/dbconnection");
const config = require("../conf/config.json");
const authMiddleware = require("../middleware/authMiddleware");
const adminMiddleware = require("../middleware/adminMiddleware");
const { tableExists } = require("../utils/dbUtils");

const FACILITY_LOG_TABLES = [
    { name: "벨트 1호기", table: "belt1_logs" },
    { name: "로프 2호기", table: "rope2_logs" },
    { name: "벨트 2호기", table: "belt2_logs" },
    { name: "로프 6호기", table: "rope6_logs" },
];

const WORK_START_HOUR = 9;
const IDLE_THRESHOLD_MINUTES = 30;

function formatDateTime(date) {
    const pad = (n) => String(n).padStart(2, "0");

    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} `
        + `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}

function diffMinutes(from, to) {
    return Math.max(0, Math.floor((to.getTime() - from.getTime()) / 60000));
}

router.post("/getCompletedWorkChart", authMiddleware, async (req, res) => {
    try {
        const startDate = req.body.startDate;
        const endDate = req.body.endDate;

        if (!startDate || !endDate) {
            return res.status(400).json({
                ok: false,
                msg: "startDate, endDate가 필요합니다.",
            });
        }

        const rows = await query(
            `
            WITH RECURSIVE dates AS (
                SELECT DATE(?) AS work_date

                UNION ALL

                SELECT DATE_ADD(work_date, INTERVAL 1 DAY)
                FROM dates
                WHERE work_date < DATE(?)
            )

            SELECT
                DATE_FORMAT(d.work_date, '%Y-%m-%d') AS date,
                COUNT(e.id) AS count
            FROM dates d
            LEFT JOIN \`jinsungmes\`.erp_cutting_list e
                ON DATE(e.created_at) = d.work_date
                AND e.status = '완료'
            GROUP BY d.work_date
            ORDER BY d.work_date ASC
            `,
            [startDate, endDate]
        );

        return res.json({
            ok: true,
            data: rows,
        });

    } catch (err) {
        console.error("[getCompletedWorkChart ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "오류 발생",
            error: process.env.NODE_ENV === "development"
                ? err.message
                : undefined,
        });
    }
});

router.post("/getDeliveryComplianceChart", authMiddleware, async (req, res) => {
    try {
        const { startDate, endDate } = req.body;

        if (!startDate || !endDate) {
            return res.status(400).json({
                ok: false,
                msg: "startDate, endDate가 필요합니다.",
            });
        }

        const rows = await query(
            `
            SELECT
                SUM(
                    CASE
                        WHEN status = '완료'
                         AND updated_at <= structure_dt
                        THEN 1
                        ELSE 0
                    END
                ) AS delivery_success,

                SUM(
                    CASE
                        WHEN updated_at > structure_dt
                        THEN 1
                        ELSE 0
                    END
                ) AS delivery_fail

            FROM \`jinsungmes\`.erp_cutting_list
            WHERE created_at >= ?
              AND created_at < DATE_ADD(?, INTERVAL 1 DAY)
            `,
            [startDate, endDate]
        );

        const row = rows[0] ?? {};

        return res.json({
            ok: true,
            data: [
                {
                    name: "납기 준수",
                    count: Number(row.delivery_success ?? 0),
                },
                {
                    name: "납기 미준수",
                    count: Number(row.delivery_fail ?? 0),
                },
            ],
        });

    } catch (err) {
        console.error("[getDeliveryComplianceChart ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "오류 발생",
            error:
                process.env.NODE_ENV === "development"
                    ? err.message
                    : undefined,
        });
    }
});

router.post("/getFaultRateChart", authMiddleware, async (req, res) => {
    try {
        const {
            measureStartTimeRange,
            measureEndTimeRange,
        } = req.body;

        const beltWhere = [];
        const ropeWhere = [];
        const params = [];

        if (measureStartTimeRange && measureEndTimeRange) {
            beltWhere.push(`a.datetime BETWEEN ? AND ?`);
            params.push(measureStartTimeRange, measureEndTimeRange);

            ropeWhere.push(`r.datetime BETWEEN ? AND ?`);
            params.push(measureStartTimeRange, measureEndTimeRange);
        }

        const beltPassCondition = `
            CAST(a.Rope_left AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
            AND CAST(a.Rope_Center AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
            AND CAST(a.Rope_Right AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
        `;

        const ropeActualCuttingMeter = `
            CAST(r.cutting_meter AS DECIMAL(10,3)) / 10
        `;

        const ropePassCondition = `
            r.cutting_meter IS NOT NULL
            AND r.meter IS NOT NULL
            AND mm.rope_min IS NOT NULL
            AND mm.rope_max IS NOT NULL
            AND (${ropeActualCuttingMeter})
                BETWEEN
                    CAST(r.meter AS DECIMAL(10,3)) - CAST(mm.rope_min AS DECIMAL(10,3))
                AND
                    CAST(r.meter AS DECIMAL(10,3)) + CAST(mm.rope_max AS DECIMAL(10,3))
        `;

        const beltOutlierExcludeCondition = `
            CAST(a.Rope_left AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
            AND CAST(a.Rope_Center AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
            AND CAST(a.Rope_Right AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
        `;

        beltWhere.push(`(${beltOutlierExcludeCondition})`);

        const ropeOutlierExcludeCondition = `
            r.cutting_meter IS NOT NULL
            AND r.meter IS NOT NULL
            AND mm.rope_min IS NOT NULL
            AND mm.rope_max IS NOT NULL
            AND ABS(
                (${ropeActualCuttingMeter}) - CAST(r.meter AS DECIMAL(10,3))
            ) <= GREATEST(
                CAST(mm.rope_min AS DECIMAL(10,3)),
                CAST(mm.rope_max AS DECIMAL(10,3))
            ) * 2
        `;

        ropeWhere.push(`(${ropeOutlierExcludeCondition})`);

        const beltWhereSql = beltWhere.length
            ? `WHERE ${beltWhere.join(" AND ")}`
            : "";

        const ropeWhereSql = ropeWhere.length
            ? `WHERE ${ropeWhere.join(" AND ")}`
            : "";

        const rows = await query(
            `
            WITH belt_data AS (
                SELECT
                    DATE_FORMAT(a.datetime, '%Y-%m-%d') AS date,
                    COUNT(*) AS totalCount,
                    SUM(CASE WHEN NOT (${beltPassCondition}) THEN 1 ELSE 0 END) AS faultCount
                FROM \`belt1\`.thickness a

                INNER JOIN (
                    SELECT MAX(no) AS no
                    FROM \`belt1\`.thickness
                    GROUP BY meter, bon, datetime
                ) x ON x.no = a.no

                JOIN (
                    SELECT
                        MAX(CASE WHEN type = 'belt_min' THEN CAST(level AS DECIMAL(10,3)) END) AS belt_min,
                        MAX(CASE WHEN type = 'belt_max' THEN CAST(level AS DECIMAL(10,3)) END) AS belt_max
                    FROM \`boas-se\`.tb_sensor_data_min_max
                    WHERE type IN ('belt_min', 'belt_max')
                ) mm

                ${beltWhereSql}

                GROUP BY DATE_FORMAT(a.datetime, '%Y-%m-%d')
            ),

            rope_data AS (
                SELECT
                    DATE_FORMAT(r.datetime, '%Y-%m-%d') AS date,
                    COUNT(*) AS totalCount,
                    SUM(CASE WHEN NOT (${ropePassCondition}) THEN 1 ELSE 0 END) AS faultCount
                FROM (
                    SELECT 'rope2' AS source_schema, ju.*
                    FROM \`rope2\`.job_update ju

                    UNION ALL

                    SELECT 'rope6' AS source_schema, ju.*
                    FROM \`rope6\`.job_update ju
                ) r

                JOIN (
                    SELECT
                        MAX(CASE WHEN type = 'rope_min' THEN CAST(level AS DECIMAL(10,3)) END) AS rope_min,
                        MAX(CASE WHEN type = 'rope_max' THEN CAST(level AS DECIMAL(10,3)) END) AS rope_max
                    FROM \`boas-se\`.tb_sensor_data_min_max
                    WHERE type IN ('rope_min', 'rope_max')
                ) mm

                ${ropeWhereSql}

                GROUP BY DATE_FORMAT(r.datetime, '%Y-%m-%d')
            ),

            merged_data AS (
                SELECT
                    date,
                    'belt' AS type,
                    totalCount,
                    faultCount
                FROM belt_data

                UNION ALL

                SELECT
                    date,
                    'rope' AS type,
                    totalCount,
                    faultCount
                FROM rope_data
            ),

            total_data AS (
                SELECT
                    date,
                    'total' AS type,
                    SUM(totalCount) AS totalCount,
                    SUM(faultCount) AS faultCount
                FROM merged_data
                GROUP BY date
            )

            SELECT
                date,
                type,
                totalCount,
                faultCount,
                ROUND(faultCount / totalCount * 100, 2) AS faultRate
            FROM (
                SELECT * FROM merged_data
                UNION ALL
                SELECT * FROM total_data
            ) result
            ORDER BY date, FIELD(type, 'belt', 'rope', 'total')
            `,
            params
        );

        return res.json({
            ok: true,
            chart: {
                belt: rows.filter(row => row.type === "belt"),
                rope: rows.filter(row => row.type === "rope"),
                total: rows.filter(row => row.type === "total"),
            },
        });

    } catch (err) {
        console.error("[getFaultRateChart ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "불량률 차트 조회 중 오류가 발생했습니다.",
            error: process.env.NODE_ENV === "development"
                ? err.message
                : undefined,
        });
    }
});

router.post("/getDeliveryComplianceRateChart", authMiddleware, async (req, res) => {
    try {
        const { startDate, endDate } = req.body;

        if (!startDate || !endDate) {
            return res.status(400).json({
                ok: false,
                msg: "startDate, endDate가 필요합니다.",
            });
        }

        const rows = await query(
            `
            SELECT
                DATE_FORMAT(created_at, '%Y-%m-%d') AS date,

                SUM(
                    CASE
                        WHEN status = '완료'
                         AND updated_at <= structure_dt
                        THEN 1
                        ELSE 0
                    END
                ) AS delivery_success,

                SUM(
                    CASE
                        WHEN updated_at > structure_dt
                        THEN 1
                        ELSE 0
                    END
                ) AS delivery_fail

            FROM \`jinsungmes\`.erp_cutting_list
            WHERE created_at >= ?
              AND created_at < DATE_ADD(?, INTERVAL 1 DAY)
            GROUP BY DATE_FORMAT(created_at, '%Y-%m-%d')
            ORDER BY DATE_FORMAT(created_at, '%Y-%m-%d')
            `,
            [startDate, endDate]
        );

        const data = rows.map(row => {
            const success = Number(row.delivery_success ?? 0);
            const fail = Number(row.delivery_fail ?? 0);
            const total = success + fail;

            return {
                date: row.date,
                deliverySuccess: success,
                deliveryFail: fail,
                total,
                complianceRate: total === 0
                    ? 0
                    : Number(((success / total) * 100).toFixed(1)),
            };
        });

        return res.json({
            ok: true,
            data,
        });

    } catch (err) {
        console.error("[getDeliveryComplianceRateChart ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "오류 발생",
            error:
                process.env.NODE_ENV === "development"
                    ? err.message
                    : undefined,
        });
    }
});

router.post("/getDeliveryImminentList", authMiddleware, async (req, res) => {
    try {
        const {
            startDate,
            endDate,
            limitStartCount = 0,
            limitEndCount = 30,
        } = req.body;

        if (!startDate || !endDate) {
            return res.status(400).json({
                ok: false,
                msg: "startDate, endDate가 필요합니다.",
            });
        }

        const rows = await query(
            `
            SELECT
                a.num,
                b.company AS companyName,
                DATE_FORMAT(a.structure_dt, '%Y-%m-%d') AS deliveryDeadLine,
                DATE_FORMAT(a.updated_at, '%Y-%m-%d') AS deliveryDay
            FROM \`jinsungmes\`.erp_cutting_list a
            LEFT JOIN \`jinsungmes\`.erp_cutting_master b
                ON a.parent_id = b.id
            WHERE a.status IN ('대기', '부분완료')
              AND a.structure_dt >= CURDATE()
              AND a.structure_dt BETWEEN ? AND ?
            ORDER BY a.structure_dt ASC
            LIMIT ?, ?
            `,
            [
                startDate,
                endDate,
                Number(limitStartCount),
                Number(limitEndCount),
            ]
        );

        return res.json({
            ok: true,
            data: rows,
        });

    } catch (err) {
        console.error("[getDeliveryImminentList ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "오류 발생",
        });
    }
});

router.post("/getDeliveryDelayList", authMiddleware, async (req, res) => {
    try {
        const {
            startDate,
            endDate,
            limitStartCount = 0,
            limitEndCount = 30,
        } = req.body;

        if (!startDate || !endDate) {
            return res.status(400).json({
                ok: false,
                msg: "startDate, endDate가 필요합니다.",
            });
        }

        const rows = await query(
            `
            SELECT
                a.num,
                b.company AS companyName,
                DATE_FORMAT(a.structure_dt, '%Y-%m-%d') AS deliveryDeadLine,
                DATEDIFF(CURDATE(), a.structure_dt) AS delayDay
            FROM \`jinsungmes\`.erp_cutting_list a
            LEFT JOIN \`jinsungmes\`.erp_cutting_master b
                ON a.parent_id = b.id
            WHERE a.status IN ('대기', '부분완료')
              AND a.structure_dt < CURDATE()
              AND a.structure_dt BETWEEN ? AND ?
            ORDER BY a.structure_dt ASC
            LIMIT ?, ?
            `,
            [
                startDate,
                endDate,
                Number(limitStartCount),
                Number(limitEndCount),
            ]
        );

        return res.json({
            ok: true,
            data: rows,
        });

    } catch (err) {
        console.error("[getDeliveryDelayList ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "오류 발생",
        });
    }
});

router.post("/getFaultRateTrendChart", authMiddleware, async (req, res) => {
    try {
        const {
            measureStartTimeRange,
            measureEndTimeRange,
        } = req.body;

        const params = [];

        const beltWhere = [];
        const ropeWhere = [];

        if (measureStartTimeRange && measureEndTimeRange) {
            beltWhere.push(`a.datetime BETWEEN ? AND ?`);
            params.push(measureStartTimeRange, measureEndTimeRange);

            ropeWhere.push(`r.datetime BETWEEN ? AND ?`);
            params.push(measureStartTimeRange, measureEndTimeRange);
        }

        const beltPassCondition = `
            CAST(a.Rope_left AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
            AND CAST(a.Rope_Center AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
            AND CAST(a.Rope_Right AS DECIMAL(10,3)) BETWEEN mm.belt_min AND mm.belt_max
        `;

        const ropeActualCuttingMeter = `
            CAST(r.cutting_meter AS DECIMAL(10,3)) / 10
        `;

        const ropePassCondition = `
            r.cutting_meter IS NOT NULL
            AND r.meter IS NOT NULL
            AND mm.rope_min IS NOT NULL
            AND mm.rope_max IS NOT NULL
            AND (${ropeActualCuttingMeter})
                BETWEEN
                    CAST(r.meter AS DECIMAL(10,3)) - CAST(mm.rope_min AS DECIMAL(10,3))
                AND
                    CAST(r.meter AS DECIMAL(10,3)) + CAST(mm.rope_max AS DECIMAL(10,3))
        `;

        const beltOutlierExcludeCondition = `
            CAST(a.Rope_left AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
            AND CAST(a.Rope_Center AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
            AND CAST(a.Rope_Right AS DECIMAL(10,3))
                BETWEEN mm.belt_min - ((mm.belt_max - mm.belt_min) * 2)
                AND mm.belt_max + ((mm.belt_max - mm.belt_min) * 2)
        `;

        beltWhere.push(`(${beltOutlierExcludeCondition})`);

        const ropeOutlierExcludeCondition = `
            r.cutting_meter IS NOT NULL
            AND r.meter IS NOT NULL
            AND mm.rope_min IS NOT NULL
            AND mm.rope_max IS NOT NULL
            AND ABS(
                (${ropeActualCuttingMeter}) - CAST(r.meter AS DECIMAL(10,3))
            ) <= GREATEST(
                CAST(mm.rope_min AS DECIMAL(10,3)),
                CAST(mm.rope_max AS DECIMAL(10,3))
            ) * 2
        `;

        ropeWhere.push(`(${ropeOutlierExcludeCondition})`);

        const beltWhereSql = beltWhere.length
            ? `WHERE ${beltWhere.join(" AND ")}`
            : "";

        const ropeWhereSql = ropeWhere.length
            ? `WHERE ${ropeWhere.join(" AND ")}`
            : "";

        const rows = await query(
            `
            WITH belt_data AS (
                SELECT
                    DATE_FORMAT(a.datetime, '%Y-%m-%d') AS date,
                    COUNT(*) AS totalCount,
                    SUM(CASE WHEN NOT (${beltPassCondition}) THEN 1 ELSE 0 END) AS faultCount
                FROM \`belt1\`.thickness a

                INNER JOIN (
                    SELECT MAX(no) AS no
                    FROM \`belt1\`.thickness
                    GROUP BY meter, bon, datetime
                ) x ON x.no = a.no

                JOIN (
                    SELECT
                        MAX(CASE WHEN type = 'belt_min' THEN CAST(level AS DECIMAL(10,3)) END) AS belt_min,
                        MAX(CASE WHEN type = 'belt_max' THEN CAST(level AS DECIMAL(10,3)) END) AS belt_max
                    FROM \`boas-se\`.tb_sensor_data_min_max
                    WHERE type IN ('belt_min', 'belt_max')
                ) mm

                ${beltWhereSql}

                GROUP BY DATE_FORMAT(a.datetime, '%Y-%m-%d')
            ),

            rope_data AS (
                SELECT
                    DATE_FORMAT(r.datetime, '%Y-%m-%d') AS date,
                    COUNT(*) AS totalCount,
                    SUM(CASE WHEN NOT (${ropePassCondition}) THEN 1 ELSE 0 END) AS faultCount
                FROM (
                    SELECT ju.*
                    FROM \`rope2\`.job_update ju

                    UNION ALL

                    SELECT ju.*
                    FROM \`rope6\`.job_update ju
                ) r

                JOIN (
                    SELECT
                        MAX(CASE WHEN type = 'rope_min' THEN CAST(level AS DECIMAL(10,3)) END) AS rope_min,
                        MAX(CASE WHEN type = 'rope_max' THEN CAST(level AS DECIMAL(10,3)) END) AS rope_max
                    FROM \`boas-se\`.tb_sensor_data_min_max
                    WHERE type IN ('rope_min', 'rope_max')
                ) mm

                ${ropeWhereSql}

                GROUP BY DATE_FORMAT(r.datetime, '%Y-%m-%d')
            ),

            merged_data AS (
                SELECT * FROM belt_data
                UNION ALL
                SELECT * FROM rope_data
            )

            SELECT
                date,
                SUM(totalCount) AS totalCount,
                SUM(faultCount) AS faultCount,
                ROUND(
                    SUM(faultCount) / NULLIF(SUM(totalCount), 0) * 100,
                    2
                ) AS faultRate
            FROM merged_data
            GROUP BY date
            ORDER BY date ASC
            `,
            params
        );

        return res.json({
            ok: true,
            chart: rows,
        });

    } catch (err) {
        console.error("[getFaultRateTrendChart ERROR]");
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "불량률 추이 차트 조회 중 오류가 발생했습니다.",
            error: process.env.NODE_ENV === "development"
                ? err.message
                : undefined,
        });
    }
});

router.post("/getFacilityStatus", authMiddleware, async (req, res) => {
    try {
        const now = new Date();

        const workStart = new Date();
        workStart.setHours(WORK_START_HOUR, 0, 0, 0);

        const workMinutes = diffMinutes(workStart, now);

        const results = await Promise.all(
            FACILITY_LOG_TABLES.map(async (facility) => {
                const exists = await tableExists('device_mqtt', facility.table);

                if (!exists) {
                    return {
                        name: facility.name,
                        utilizationRate: 0,
                        activeTime: 0,
                        nonActiveTime: workMinutes,
                        status: "미설치",
                    };
                }
                
                const rows = await query(
                    `
                    SELECT
                        seq,
                        column_name,
                        db_insert_time
                    FROM device_mqtt.\`${facility.table}\`
                    WHERE db_insert_time >= ?
                      AND db_insert_time <= ?
                      AND column_name IN ('cycle_start', 'cycle_end')
                    ORDER BY db_insert_time ASC, seq ASC
                    `,
                    [formatDateTime(workStart), formatDateTime(now)]
                );

                if (!rows.length || workMinutes <= 0) {
                    return {
                        name: facility.name,
                        utilizationRate: 0,
                        activeTime: 0,
                        nonActvieTime: workMinutes,
                        status: "비가동",
                    };
                }

                let nonActiveMinutes = 0;
                let lastEndTime = null;
                let lastStartTime = null;
                let lastEvent = rows[rows.length - 1];

                const firstEventTime = new Date(rows[0].db_insert_time);

                // 09:00 이후 첫 시작 전까지도 비가동으로 계산
                if (rows[0].column_name === "cycle_start") {
                    const firstGap = diffMinutes(workStart, firstEventTime);

                    if (firstGap > IDLE_THRESHOLD_MINUTES) {
                        nonActiveMinutes += firstGap;
                    }
                }

                for (const row of rows) {
                    const eventTime = new Date(row.db_insert_time);

                    if (row.column_name === "cycle_end") {
                        lastEndTime = eventTime;
                    }

                    if (row.column_name === "cycle_start") {
                        lastStartTime = eventTime;

                        if (lastEndTime) {
                            const gap = diffMinutes(lastEndTime, eventTime);

                            if (gap > IDLE_THRESHOLD_MINUTES) {
                                nonActiveMinutes += gap;
                            }

                            lastEndTime = null;
                        }
                    }
                }

                // 마지막이 완료 상태이고 지금까지 30분 초과로 시작이 없으면 비가동 누적
                if (lastEvent.column_name === "cycle_end") {
                    const lastEndGap = diffMinutes(new Date(lastEvent.db_insert_time), now);

                    if (lastEndGap > IDLE_THRESHOLD_MINUTES) {
                        nonActiveMinutes += lastEndGap;
                    }
                }

                nonActiveMinutes = Math.min(nonActiveMinutes, workMinutes);

                const activeMinutes = Math.max(0, workMinutes - nonActiveMinutes);

                const utilizationRate = workMinutes > 0
                    ? Number(((activeMinutes / workMinutes) * 100).toFixed(1))
                    : 0;

                const status = lastEvent.column_name === "cycle_start"
                    ? "가동중"
                    : diffMinutes(new Date(lastEvent.db_insert_time), now) > IDLE_THRESHOLD_MINUTES
                        ? "비가동"
                        : "대기";

                return {
                    name: facility.name,
                    utilizationRate,
                    activeTime: activeMinutes,
                    nonActiveTime: nonActiveMinutes,
                    status,
                };
            })
        );

        return res.json({
            ok: true,
            data: results,
        });
    } catch (err) {
        console.error(err);

        return res.status(500).json({
            ok: false,
            msg: "설비 상태 조회 중 오류가 발생했습니다.",
        });
    }
});

module.exports = router;