<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
/**
 * Helper Notifikasi & Rekap Laporan Katim v4
 * Fix: canonical map lengkap sesuai data DB nyata (semua duplikat tertangani)
 */

if (!function_exists('_katim_do_canonical_key')) {
    function _katim_do_canonical_key(string $n): string
    {
        if ($n === 'IGD') return 'IGD';
        if (in_array($n, ['VK','VK KAMAR BERSALIN','KAMAR BERSALIN (VK)','KAMAR BERSALIN','VKKB','VK  KAMAR BERSALIN'], true) || str_contains($n, 'BERSALIN')) return 'VK';
        if (in_array($n, ['OK','OK KAMAR OPERASI','KAMAR OPERASI','OKKO','OK  KAMAR OPERASI'], true) || str_contains($n, 'KAMAR OPERASI') || $n === 'OKKO') return 'OK';
        if (in_array($n, ['POLIKLINIK','POLI'], true)) return 'POLI';
        if (in_array($n, ['HD','HD HEMODIALISA','HD HEMODIALISIS','HEMODIALISA','HEMODIALISIS','HEMODIALISIS (HD)','HDH','HD  HEMODIALISA','HD  HEMODIALISIS'], true) || str_contains($n, 'HEMODIAL')) return 'HD';
        if (str_contains($n, 'CANIGARA')) return 'CANIGARA';
        if (str_contains($n, 'CEMPAKA UTARA') || str_contains($n, 'CEMPAKAUTARA') || $n === 'CU') return 'CEMPAKA_UTARA';
        if (str_contains($n, 'CEMPAKA')) return 'CEMPAKA';
        if (str_contains($n, 'CENDANA') || $n === 'PC') return 'CENDANA';
        if (str_contains($n, 'BAYI') && str_contains($n, 'NICU')) return 'BAYI_NICU';
        if ($n === 'NICU') return 'NICU';
        if (str_contains($n, 'BAYI') || $n === 'RB') return 'BAYI';
        if ($n === 'ICU') return 'ICU';
        return $n;
    }
}

if (!function_exists('katim_target_unit_codes')) {
    function katim_target_unit_codes(): array
    {
        return [
            'IGD',
            'VK','KAMARBERSA','VKKB',
            'OK','OKKO',
            'POLI','POLIKLINIK','P',
            'HD','HDH','HEMODIALIS',
            'CANIGARA','PAVCANIGARA',
            'CEMPAKAUTARA','CU',
            'CEMPAKA','PAVCEMPAKA',
            'CENDANA','PAVCENDANA','PC',
            'RBYT_NICU',
            'RUANGBAYI','RB',
            'NICU',
            'ICU',
        ];
    }
}

if (!function_exists('katim_target_unit_name_keys')) {
    function katim_target_unit_name_keys(): array
    {
        return [
            'IGD',
            'VK','VK KAMAR BERSALIN','KAMAR BERSALIN','VK / KAMAR BERSALIN','KAMAR BERSALIN (VK)',
            'OK','OK KAMAR OPERASI','KAMAR OPERASI','OK / KAMAR OPERASI',
            'POLIKLINIK',
            'HD','HD / HEMODIALISA','HD HEMODIALISA','HEMODIALISA','HEMODIALISIS','HEMODIALISIS (HD)','HD / HEMODIALISIS',
            'PAV CANIGARA','PAVCANIGARA','CANIGARA','PAV. CANIGARA',
            'CEMPAKA UTARA','CEMPAKAUTARA',
            'PAV CEMPAKA','PAVCEMPAKA','CEMPAKA','PAV. CEMPAKA',
            'PAV CENDANA','PAVCENDANA','CENDANA','PAV. CENDANA',
            'R. BAYI DAN NICU','R BAYI DAN NICU','RUANG BAYI DAN NICU',
            'RUANG BAYI','RUANGBAYI',
            'NICU',
            'ICU',
        ];
    }
}

if (!function_exists('katim_unit_normalize_sql')) {
    function katim_unit_normalize_sql(string $column): string
    {
        return "UPPER(TRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE($column, '.', ''), '/', ' '), '-', ' '), '_', ' '), '  ', ' ')))";
    }
}

if (!function_exists('katim_normalize_unit_name')) {
    function katim_normalize_unit_name(string $name): string
    {
        $name = strtoupper(trim($name));
        $name = str_replace(['.', '/', '-', '_'], ['',' ',' ',' '], $name);
        $name = preg_replace('/\s+/', ' ', $name);
        return trim($name);
    }
}

if (!function_exists('katim_unit_canonical_key')) {
    function katim_unit_canonical_key(string $normalizedName): string
    {
        return _katim_do_canonical_key($normalizedName);
    }
}

if (!function_exists('katim_get_target_units')) {
    function katim_get_target_units(mysqli $conn): array
    {
        $codes    = katim_target_unit_codes();
        $nameKeys = katim_target_unit_name_keys();

        $codePlaceholders = implode(',', array_fill(0, count($codes),    '?'));
        $namePlaceholders = implode(',', array_fill(0, count($nameKeys), '?'));
        $nameExpr         = katim_unit_normalize_sql('u.name');

        $sql = "
            SELECT DISTINCT u.id, u.code, u.name
            FROM units u
            WHERE u.is_active = 1
              AND (
                    UPPER(TRIM(u.code)) IN ($codePlaceholders)
                    OR $nameExpr        IN ($namePlaceholders)
                  )
            ORDER BY u.id ASC
        ";

        $stmt = $conn->prepare($sql);
        if (!$stmt) return [];

        $params = array_merge($codes, $nameKeys);
        $types  = str_repeat('s', count($params));
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        $res = $stmt->get_result();

        $allRows = [];
        while ($row = $res->fetch_assoc()) {
            $allRows[] = [
                'id'   => (int)$row['id'],
                'code' => (string)($row['code'] ?? ''),
                'name' => (string)($row['name'] ?? ''),
            ];
        }
        $stmt->close();

        // Deduplikasi berdasarkan canonical key
        $canonicalMap = [];
        foreach ($allRows as $row) {
            $normalized   = katim_normalize_unit_name($row['name']);
            $canonicalKey = katim_unit_canonical_key($normalized);

            if (!isset($canonicalMap[$canonicalKey])) {
                $canonicalMap[$canonicalKey] = [
                    'row'     => $row,
                    'all_ids' => [$row['id']],
                ];
            } else {
                $canonicalMap[$canonicalKey]['all_ids'][] = $row['id'];
            }
        }

        $result = [];
        foreach ($canonicalMap as $canonicalKey => $entry) {
            $result[] = [
                'id'            => $entry['row']['id'],
                'code'          => $entry['row']['code'],
                'name'          => $entry['row']['name'],
                'canonical_key' => $canonicalKey,
                'all_ids'       => array_unique($entry['all_ids']),
            ];
        }

        return $result;
    }
}

if (!function_exists('katim_shift_definitions')) {
    function katim_shift_definitions(): array
    {
        return [
            'Pagi'  => ['start' => '07:00:00', 'due' => '14:00:00', 'due_day_offset' => 0],
            'Sore'  => ['start' => '14:00:00', 'due' => '21:00:00', 'due_day_offset' => 0],
            'Malam' => ['start' => '21:00:00', 'due' => '07:00:00', 'due_day_offset' => 1],
        ];
    }
}

if (!function_exists('katim_format_tanggal_indonesia')) {
    function katim_format_tanggal_indonesia(string $tanggal): string
    {
        $ts = strtotime($tanggal);
        return $ts ? date('d-m-Y', $ts) : $tanggal;
    }
}

if (!function_exists('katim_shift_previous_context')) {
    function katim_shift_previous_context(?DateTime $now = null): array
    {
        $now  = $now ?: new DateTime('now');
        $hour = (int)$now->format('H');

        if ($hour >= 14 && $hour < 21) return ['tanggal' => $now->format('Y-m-d'), 'shift' => 'Pagi',  'current_shift' => 'Sore'];
        if ($hour >= 21)               return ['tanggal' => $now->format('Y-m-d'), 'shift' => 'Sore',  'current_shift' => 'Malam'];

        $yesterday = clone $now;
        $yesterday->modify('-1 day');

        if ($hour >= 7) return ['tanggal' => $yesterday->format('Y-m-d'), 'shift' => 'Malam', 'current_shift' => 'Pagi'];
        return              ['tanggal' => $yesterday->format('Y-m-d'), 'shift' => 'Sore',  'current_shift' => 'Malam'];
    }
}

if (!function_exists('katim_get_missing_shift_alerts')) {
    function katim_get_missing_shift_alerts(mysqli $conn, ?string $tanggal = null, ?string $shift = null): array
    {
        $now = new DateTime('now');

        $checks = [];

        if ($tanggal && $shift) {
            $checks[] = ['tanggal' => $tanggal, 'shift' => $shift];
        } else {
            $defs        = katim_shift_definitions();
            $windowStart = clone $now;
            $windowStart->modify('-24 hours');

            for ($d = -2; $d <= 0; $d++) {
                $base        = clone $now;
                if ($d !== 0) $base->modify($d . ' day');
                $baseTanggal = $base->format('Y-m-d');

                foreach ($defs as $shiftName => $def) {
                    $dueDate = new DateTime($baseTanggal . ' ' . $def['due']);
                    if ((int)$def['due_day_offset'] !== 0) $dueDate->modify('+' . (int)$def['due_day_offset'] . ' day');
                    if ($now >= $dueDate && $dueDate >= $windowStart) {
                        $checks[] = ['tanggal' => $baseTanggal, 'shift' => $shiftName];
                    }
                }
            }

            $seen   = [];
            $checks = array_filter($checks, function ($c) use (&$seen) {
                $k = $c['tanggal'] . '|' . $c['shift'];
                if (isset($seen[$k])) return false;
                $seen[$k] = true;
                return true;
            });
            $checks = array_values($checks);
        }

        if (empty($checks)) return [];

        $units = katim_get_target_units($conn);
        if (empty($units)) return [];

        $allUnitIds = [];
        foreach ($units as $u) {
            foreach ($u['all_ids'] as $id) $allUnitIds[] = (int)$id;
        }
        $allUnitIds = array_unique($allUnitIds);

        $idToCanonical = [];
        foreach ($units as $u) {
            foreach ($u['all_ids'] as $id) $idToCanonical[(int)$id] = $u['canonical_key'];
        }

        $allTanggal = array_unique(array_column($checks, 'tanggal'));
        $allShift   = array_unique(array_column($checks, 'shift'));

        $tPh = implode(',', array_fill(0, count($allTanggal), '?'));
        $sPh = implode(',', array_fill(0, count($allShift),   '?'));
        $uPh = implode(',', array_fill(0, count($allUnitIds), '?'));

        $sqlBulk = "
            SELECT unit_id, tanggal, shift
            FROM laporan_katim
            WHERE unit_id IN ($uPh)
              AND tanggal  IN ($tPh)
              AND shift    IN ($sPh)
        ";

        $params = array_merge($allUnitIds, $allTanggal, $allShift);
        $types  = str_repeat('i', count($allUnitIds))
                . str_repeat('s', count($allTanggal))
                . str_repeat('s', count($allShift));

        $reported = [];
        $stmtBulk = $conn->prepare($sqlBulk);
        if ($stmtBulk) {
            $stmtBulk->bind_param($types, ...$params);
            $stmtBulk->execute();
            $res = $stmtBulk->get_result();
            while ($row = $res->fetch_assoc()) {
                $uid = (int)$row['unit_id'];
                $ck  = $idToCanonical[$uid] ?? null;
                if ($ck === null) continue;
                $reported[(string)$row['tanggal']][(string)$row['shift']][$ck] = true;
            }
            $stmtBulk->close();
        }

        $rows     = [];
        $seenRows = [];

        foreach ($checks as $check) {
            $checkTanggal = (string)$check['tanggal'];
            $checkShift   = (string)$check['shift'];

            foreach ($units as $u) {
                $ck = $u['canonical_key'];
                if (!empty($reported[$checkTanggal][$checkShift][$ck])) continue;

                $uniqueKey = $checkTanggal . '|' . strtolower($checkShift) . '|' . $ck;
                if (isset($seenRows[$uniqueKey])) continue;
                $seenRows[$uniqueKey] = true;

                $unitName       = (string)$u['name'];
                $tanggalDisplay = katim_format_tanggal_indonesia($checkTanggal);

                $rows[] = [
                    'unit_id'         => $u['id'],
                    'unit_name'       => $unitName,
                    'tanggal'         => $checkTanggal,
                    'tanggal_display' => $tanggalDisplay,
                    'shift_name'      => $checkShift,
                    'due_at'          => null,
                    'laporan_id'      => null,
                    'message'         => 'Dinas ' . strtolower($checkShift) . ' tanggal ' . $tanggalDisplay . ' belum melapor - ' . $unitName,
                    'wa_message'      => '- Dinas ' . strtolower($checkShift) . ' tanggal ' . $tanggalDisplay . ' belum melapor - ' . $unitName,
                ];
            }
        }

        usort($rows, function ($a, $b) {
            $c = strcmp((string)$a['tanggal'], (string)$b['tanggal']);
            if ($c !== 0) return $c;
            $order = ['Pagi' => 1, 'Sore' => 2, 'Malam' => 3];
            $sa = $order[$a['shift_name']] ?? 99;
            $sb = $order[$b['shift_name']] ?? 99;
            if ($sa !== $sb) return $sa <=> $sb;
            return strcmp((string)$a['unit_name'], (string)$b['unit_name']);
        });

        return $rows;
    }
}

if (!function_exists('katim_get_daily_shift_rekap')) {
    function katim_get_daily_shift_rekap(mysqli $conn, string $startDate, string $endDate): array
    {
        $start = new DateTime($startDate);
        $end   = new DateTime($endDate);
        if ($end < $start) return [];

        $units = katim_get_target_units($conn);
        if (empty($units)) return [];

        $allUnitIds = [];
        foreach ($units as $u) {
            foreach ($u['all_ids'] as $id) $allUnitIds[] = (int)$id;
        }
        $allUnitIds = array_unique($allUnitIds);

        $idToCanonical = [];
        foreach ($units as $u) {
            foreach ($u['all_ids'] as $id) $idToCanonical[(int)$id] = $u['canonical_key'];
        }

        $placeholders = implode(',', array_fill(0, count($allUnitIds), '?'));

        $reported = [];
        $sql = "
            SELECT tanggal, unit_id, shift, COUNT(*) AS total
            FROM laporan_katim
            WHERE unit_id IN ($placeholders)
              AND tanggal BETWEEN ? AND ?
            GROUP BY tanggal, unit_id, shift
        ";

        $stmt = $conn->prepare($sql);
        if ($stmt) {
            $params = array_merge($allUnitIds, [$startDate, $endDate]);
            $types  = str_repeat('i', count($allUnitIds)) . 'ss';
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
            while ($row = $res->fetch_assoc()) {
                $uid = (int)$row['unit_id'];
                $ck  = $idToCanonical[$uid] ?? null;
                if ($ck === null) continue;
                $key            = $row['tanggal'] . '|' . $ck . '|' . strtolower((string)$row['shift']);
                $reported[$key] = ($reported[$key] ?? 0) + (int)$row['total'];
            }
            $stmt->close();
        }

        $rows   = [];
        $period = new DatePeriod(
            $start,
            new DateInterval('P1D'),
            (clone $end)->modify('+1 day')
        );

        foreach ($period as $date) {
            $tgl = $date->format('Y-m-d');
            foreach ($units as $u) {
                $ck    = $u['canonical_key'];
                $pagi  = !empty($reported[$tgl . '|' . $ck . '|pagi']);
                $sore  = !empty($reported[$tgl . '|' . $ck . '|sore']);
                $malam = !empty($reported[$tgl . '|' . $ck . '|malam']);

                $rows[] = [
                    'tanggal'        => $tgl,
                    'unit_id'        => (int)$u['id'],
                    'unit_name'      => (string)$u['name'],
                    'pagi_reported'  => $pagi  ? 1 : 0,
                    'sore_reported'  => $sore  ? 1 : 0,
                    'malam_reported' => $malam ? 1 : 0,
                    'missing_count'  => (int)!$pagi + (int)!$sore + (int)!$malam,
                ];
            }
        }

        return $rows;
    }
}