<?php
declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) session_start();
require_once __DIR__ . '/../../config/database.php';

if (!function_exists('lr_e')) {
function lr_e($v): string { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
}
function lr_conn(): mysqli { return getConnection(); }
function lr_user_id(): int { return (int)($_SESSION['user_id'] ?? $_SESSION['user']['id'] ?? 0); }
function lr_role(): string { $r=strtolower(trim((string)($_SESSION['user_role'] ?? $_SESSION['user']['role'] ?? 'viewer'))); return $r==='superadmin'?'admin':$r; }
function lr_bulan(int $m): string { return [1=>'Januari',2=>'Februari',3=>'Maret',4=>'April',5=>'Mei',6=>'Juni',7=>'Juli',8=>'Agustus',9=>'September',10=>'Oktober',11=>'November',12=>'Desember'][$m] ?? '-'; }
function lr_post(string $k, string $d=''): string { return trim((string)($_POST[$k] ?? $d)); }
function lr_int($v, int $d=0): int { $i=(int)$v; return $i ?: $d; }

function lr_logo_url(): string { return 'https://balimedhospital.co.id/wp-content/uploads/elementor/thumbs/logo-dark-o9cm6tnx14hcrnest1hge1pwnqj0yaumij7qohadlm.png'; }

function lr_default_pendahuluan(): string {
    return "Laporan keperawatan adalah gambaran terhadap pelaksanaan kegiatan keperawatan baik di rawat jalan maupun rawat inap yang mencakup ketenagaan, jumlah pasien, keberhasilan Manajemen Asuhan Keperawatan Profesional, pencapaian pelaksanaan RKA serta permasalahan terkait pelayanan keperawatan.\n\nTampilan laporan disusun oleh masing-masing kepala sub divisi berdasarkan laporan dari masing-masing kepala unit dan berdasarkan hasil pemantauan langsung serta kajian-kajian oleh kepala sub divisi.";
}

function lr_report_type_label(string $type): string { return $type==='ranap'?'RAWAT INAP':($type==='gabungan'?'KEPERAWATAN':'RAWAT JALAN'); }
function lr_subdiv_short(string $type): string { return $type==='ranap'?'RANAP':'RAJAL'; }

function lr_sections(string $level): array {
    if ($level === 'unit') {
        return [
            'ketenagaan'         => 'A. Ketenagaan',
            'jumlah_pasien'      => 'B. Jumlah Pasien',
            'keterlambatan_staf' => 'C. Keterlambatan / Disiplin Staf',
            'capaian_rka'        => 'D. Capaian RKA / Program Kerja',
            'makp'               => 'E. Keberhasilan MAKP',
            'permasalahan'       => 'F. Permasalahan Terkait Pelayanan',
            'mutu'               => 'G. Evaluasi Mutu / Monev / SPO',
            'ikp'                => 'H. Insiden Keselamatan Pasien',
        ];
    }
    if ($level === 'kadiv') {
        return [
            'ketenagaan'   => 'A. Ketenagaan',
            'jumlah_pasien'=> 'B. Jumlah Pasien / Aktivitas Pelayanan',
            'capaian_rka'  => 'C. Capaian RKA / Program Kerja',
            'makp'         => 'D. Keberhasilan MAKP',
            'permasalahan' => 'E. Permasalahan Terkait Pelayanan',
            'mutu'         => 'F. Evaluasi Mutu / Monev',
            'ikp'          => 'G. Insiden Keselamatan Pasien',
            'analisa_kadiv'=> 'H. Kesimpulan dan Analisa Kadiv',
        ];
    }
    /* kasubdiv */
    return [
        'ketenagaan'         => 'A. Ketenagaan',
        'jumlah_pasien'      => 'B. Jumlah Pasien / Aktivitas Pelayanan',
        'keterlambatan_staf' => 'C. Keterlambatan / Disiplin Staf',
        'capaian_rka'        => 'D. Capaian RKA / Program Kerja',
        'makp'               => 'E. Keberhasilan MAKP',
        'permasalahan'       => 'F. Permasalahan Terkait Pelayanan',
        'mutu'               => 'G. Evaluasi Mutu / Monev',
        'ikp'                => 'H. Insiden Keselamatan Pasien',
    ];
}

function lr_columns(string $code): array {
    /* Kolom sesuai format Word laporan bulanan RS Balimed */
    return match($code) {
        /* ── UNIT & KASUBDIV/KADIV (kolom Unit selalu ada di col1 untuk rekap) ── */
        'ketenagaan'         => ['Unit','Jumlah Tenaga','Komposisi','Keterangan'],
        'jumlah_pasien'      => ['Unit','Jumlah Pasien','Jumlah Perawat','Rasio','Keterangan / BOR'],
        'keterlambatan_staf' => ['Unit','Jumlah Staf Terlambat','Total Menit Terlambat','Keterangan'],
        'capaian_rka'        => ['Unit','Uraian Kegiatan / Project','Bulan','Capaian','Kendala'],
        'makp'               => ['Unit','Jumlah PP & PA','Tingkat Keberhasilan (%)','Kendala','RTL'],
        'permasalahan'       => ['Unit','Hari / Tgl','Permasalahan','Unit Terkait','Hasil Rapat','RTL / Realisasi'],
        'mutu'               => ['Unit','Indikator / Monev SPO','Bulan','Capaian','Analisa / RTL'],
        'ikp'                => ['Unit','Jenis Insiden','Tanggal','Kronologi Singkat','Tindak Lanjut','Keterangan'],
        'analisa_kadiv'      => ['Area / Topik','Kesimpulan','Analisa Kadiv','Rekomendasi / RTL'],
        default              => ['Unit','Uraian','Capaian','Keterangan'],
    };
}

function lr_columns_for_mode(string $code, string $mode): array {
    $cols = lr_columns($code);
    if ($mode === 'unit') {
        /* Pada level unit, kolom 'Unit' di col1 diganti dengan label yang lebih tepat per seksi */
        if (!isset($cols[0])) return $cols;
        $firstLower = strtolower(trim($cols[0]));
        if ($firstLower === 'unit') {
            /* Ganti header kolom pertama sesuai konteks, jangan hapus */
            $perSectionLabel = match($code) {
                'ketenagaan'         => 'Nama Unit',
                'jumlah_pasien'      => 'Uraian / Kelas Pasien',
                'keterlambatan_staf' => 'Nama Staf',
                'capaian_rka'        => 'No',
                'makp'               => 'No',
                'permasalahan'       => 'No',
                'mutu'               => 'SPO / Indikator',
                'ikp'                => 'No',
                default              => 'No',
            };
            $cols[0] = $perSectionLabel;
        }
    }
    return $cols;
}

function lr_unit_master(): array {
    return [
        ['code'=>'IGD','name'=>'IGD','category'=>'rawat_jalan','subdivision_id'=>1,'division_id'=>1,'report_type'=>'rajal'],
        ['code'=>'VK','name'=>'VK / Kamar Bersalin','category'=>'rawat_jalan','subdivision_id'=>1,'division_id'=>1,'report_type'=>'rajal'],
        ['code'=>'HD','name'=>'HD / Hemodialisa','category'=>'rawat_jalan','subdivision_id'=>1,'division_id'=>1,'report_type'=>'rajal'],
        ['code'=>'OK','name'=>'OK / Kamar Operasi','category'=>'rawat_jalan','subdivision_id'=>1,'division_id'=>1,'report_type'=>'rajal'],
        ['code'=>'POLI','name'=>'Poliklinik','category'=>'rawat_jalan','subdivision_id'=>1,'division_id'=>1,'report_type'=>'rajal'],
        ['code'=>'CANIGARA','name'=>'Pav. Canigara','category'=>'rawat_inap','subdivision_id'=>2,'division_id'=>1,'report_type'=>'ranap'],
        ['code'=>'RBYT_NICU','name'=>'R. Bayi dan NICU','category'=>'rawat_inap','subdivision_id'=>2,'division_id'=>1,'report_type'=>'ranap'],
        ['code'=>'CEMPAKA','name'=>'Pav. Cempaka','category'=>'rawat_inap','subdivision_id'=>2,'division_id'=>1,'report_type'=>'ranap'],
        ['code'=>'CENDANA','name'=>'Pav. Cendana','category'=>'rawat_inap','subdivision_id'=>2,'division_id'=>1,'report_type'=>'ranap'],
        ['code'=>'ICU','name'=>'ICU','category'=>'rawat_inap','subdivision_id'=>2,'division_id'=>1,'report_type'=>'ranap'],
    ];
}

function lr_ensure_schema(mysqli $conn): void {
    $conn->query("CREATE TABLE IF NOT EXISTS nursing_divisions (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(150) NOT NULL, code VARCHAR(50) NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $conn->query("CREATE TABLE IF NOT EXISTS nursing_subdivisions (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(150) NOT NULL, division_id INT NULL, code VARCHAR(50) NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, report_type ENUM('rajal','ranap','gabungan') NOT NULL DEFAULT 'rajal', created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $conn->query("CREATE TABLE IF NOT EXISTS monthly_report_headers (id INT NOT NULL AUTO_INCREMENT, report_type ENUM('rajal','ranap','gabungan') NOT NULL DEFAULT 'rajal', report_level ENUM('unit','kasubdiv','kadiv') NOT NULL, unit_id INT NULL, subdivision_id INT NULL, division_id INT NULL, bulan TINYINT NOT NULL, tahun SMALLINT NOT NULL, title VARCHAR(255) NOT NULL, pendahuluan LONGTEXT NULL, simpulan LONGTEXT NULL, penutup LONGTEXT NULL, signed_name VARCHAR(150) NULL, signed_position VARCHAR(150) NULL, status ENUM('draft','submitted','reviewed','approved','rejected','final') NOT NULL DEFAULT 'draft', parent_report_id INT NULL, created_by INT NULL, updated_by INT NULL, submitted_at DATETIME NULL, approved_at DATETIME NULL, rejected_note TEXT NULL, created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(id), KEY idx_report(report_level,bulan,tahun,unit_id,subdivision_id,division_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $conn->query("CREATE TABLE IF NOT EXISTS monthly_report_sections (id INT NOT NULL AUTO_INCREMENT, report_id INT NOT NULL, section_code VARCHAR(100) NOT NULL, section_title VARCHAR(255) NOT NULL, intro_text LONGTEXT NULL, urut INT NOT NULL DEFAULT 0, created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(id), KEY idx_report(report_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $conn->query("CREATE TABLE IF NOT EXISTS monthly_report_rows (id INT NOT NULL AUTO_INCREMENT, section_id INT NOT NULL, urut INT NOT NULL DEFAULT 0, col1 TEXT NULL, col2 TEXT NULL, col3 TEXT NULL, col4 TEXT NULL, col5 TEXT NULL, col6 TEXT NULL, col7 TEXT NULL, col8 TEXT NULL, col9 TEXT NULL, col10 TEXT NULL, notes TEXT NULL, source_row_id INT NULL, source_level ENUM('unit','kasubdiv','kadiv') NULL, created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(id), KEY idx_section(section_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $conn->query("CREATE TABLE IF NOT EXISTS monthly_report_sources (id INT NOT NULL AUTO_INCREMENT, parent_report_id INT NOT NULL, child_report_id INT NOT NULL, source_level ENUM('unit','kasubdiv') NOT NULL, created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(id), UNIQUE KEY uq_source(parent_report_id, child_report_id, source_level)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $conn->query("INSERT IGNORE INTO nursing_divisions (id,name,code,is_active) VALUES (1,'Divisi Keperawatan','DIV_KEP',1)");
    $conn->query("INSERT IGNORE INTO nursing_subdivisions (id,name,division_id,code,is_active,report_type) VALUES (1,'Kasubdiv Rawat Jalan',1,'RAJAL',1,'rajal'),(2,'Kasubdiv Rawat Inap',1,'RANAP',1,'ranap')");
    foreach (lr_unit_master() as $u) {
        $stmt=$conn->prepare("SELECT id FROM units WHERE code=? LIMIT 1");
        if ($stmt) { $stmt->bind_param('s',$u['code']); $stmt->execute(); $ex=$stmt->get_result()->fetch_assoc(); $stmt->close(); }
        else { $ex=null; }
        if ($ex) {
            $stmt=$conn->prepare("UPDATE units SET name=?, category=?, is_active=1, subdivision_id=?, division_id=?, report_type=? WHERE id=?");
            if ($stmt) { $id=(int)$ex['id']; $stmt->bind_param('ssiisi',$u['name'],$u['category'],$u['subdivision_id'],$u['division_id'],$u['report_type'],$id); $stmt->execute(); $stmt->close(); }
        } else {
            $stmt=$conn->prepare("INSERT INTO units (code,name,category,description,is_active,subdivision_id,division_id,report_type) VALUES (?,?,?,'Unit laporan bulanan keperawatan',1,?,?,?)");
            if ($stmt) { $stmt->bind_param('sssiis',$u['code'],$u['name'],$u['category'],$u['subdivision_id'],$u['division_id'],$u['report_type']); $stmt->execute(); $stmt->close(); }
        }
    }
}

function lr_units(mysqli $conn, ?int $subdivisionId=null): array {
    $sql="SELECT id,code,name,category,subdivision_id,division_id,report_type FROM units WHERE is_active=1 AND code IN ('IGD','VK','HD','OK','POLI','CANIGARA','RBYT_NICU','CEMPAKA','CENDANA','ICU')";
    if ($subdivisionId) $sql.=" AND subdivision_id=".(int)$subdivisionId;
    $sql.=" ORDER BY FIELD(code,'IGD','VK','HD','OK','POLI','CANIGARA','RBYT_NICU','CEMPAKA','CENDANA','ICU')";
    $res=$conn->query($sql); $rows=[]; if($res){while($r=$res->fetch_assoc())$rows[]=$r;} return $rows;
}

function lr_report(mysqli $conn, int $id): ?array {
    $stmt=$conn->prepare("SELECT h.*, u.name unit_name, u.code unit_code, ns.name subdivision_name, ns.report_type subdivision_report_type, nd.name division_name FROM monthly_report_headers h LEFT JOIN units u ON u.id=h.unit_id LEFT JOIN nursing_subdivisions ns ON ns.id=h.subdivision_id LEFT JOIN nursing_divisions nd ON nd.id=h.division_id WHERE h.id=? LIMIT 1");
    $stmt->bind_param('i',$id); $stmt->execute(); $row=$stmt->get_result()->fetch_assoc(); $stmt->close(); return $row?:null;
}

function lr_find_or_create_report(mysqli $conn, string $level, int $bulan, int $tahun, ?int $unitId, ?int $subdivisionId, ?int $divisionId, string $type, int $userId): int {
    $where="report_level=? AND bulan=? AND tahun=?"; $types='sii'; $vals=[$level,$bulan,$tahun];
    if ($level==='unit') { $where.=" AND unit_id=?"; $types.='i'; $vals[]=$unitId; }
    elseif ($level==='kasubdiv') { $where.=" AND subdivision_id=?"; $types.='i'; $vals[]=$subdivisionId; }
    else { $where.=" AND division_id=?"; $types.='i'; $vals[]=$divisionId; }
    $stmt=$conn->prepare("SELECT id FROM monthly_report_headers WHERE $where LIMIT 1");
    $stmt->bind_param($types, ...$vals); $stmt->execute(); $ex=$stmt->get_result()->fetch_assoc(); $stmt->close();
    if ($ex) return (int)$ex['id'];
    $unitName=''; if($unitId){$s=$conn->prepare("SELECT name FROM units WHERE id=?");$s->bind_param('i',$unitId);$s->execute();$unitName=(string)($s->get_result()->fetch_assoc()['name']??'UNIT');$s->close();}
    $title = match($level){
        'unit' => 'LAPORAN BULANAN UNIT '.strtoupper($unitName).' - '.lr_bulan($bulan).' '.$tahun,
        'kadiv' => 'LAPORAN BULANAN KADIV KEPERAWATAN - '.lr_bulan($bulan).' '.$tahun,
        default => 'LAPORAN BULANAN KASUBDIV '.lr_subdiv_short($type).' - '.lr_bulan($bulan).' '.$tahun,
    };
    $pend = $level==='unit' ? '' : lr_default_pendahuluan();
    $stmt=$conn->prepare("INSERT INTO monthly_report_headers (report_type,report_level,unit_id,subdivision_id,division_id,bulan,tahun,title,pendahuluan,status,created_by,updated_by) VALUES (?,?,?,?,?,?,?,?,?,'draft',?,?)");
    $stmt->bind_param('ssiiiisssii',$type,$level,$unitId,$subdivisionId,$divisionId,$bulan,$tahun,$title,$pend,$userId,$userId); $stmt->execute(); $id=(int)$stmt->insert_id; $stmt->close();
    $i=1; foreach(lr_sections($level) as $code=>$st){$stmt=$conn->prepare("INSERT INTO monthly_report_sections (report_id,section_code,section_title,urut) VALUES (?,?,?,?)");$stmt->bind_param('issi',$id,$code,$st,$i);$stmt->execute();$stmt->close();$i++;}
    return $id;
}

function lr_sync_sections(mysqli $conn, int $reportId, string $level): void {
    /* Pastikan laporan (termasuk yang dibuat sebelum update skema) punya semua section terbaru. */
    $existing = [];
    $res = $conn->query("SELECT section_code, MAX(urut) u FROM monthly_report_sections WHERE report_id=".(int)$reportId." GROUP BY section_code");
    if ($res) while ($r = $res->fetch_assoc()) { $existing[$r['section_code']] = (int)$r['u']; }
    $i = count($existing) + 1;
    foreach (lr_sections($level) as $code => $title) {
        if (isset($existing[$code])) continue;
        $stmt = $conn->prepare("INSERT INTO monthly_report_sections (report_id,section_code,section_title,urut) VALUES (?,?,?,?)");
        $stmt->bind_param('issi', $reportId, $code, $title, $i);
        $stmt->execute(); $stmt->close();
        $i++;
    }
}

function lr_sections_with_rows(mysqli $conn, int $reportId): array {
    $out=[]; $stmt=$conn->prepare("SELECT * FROM monthly_report_sections WHERE report_id=? ORDER BY urut,id"); $stmt->bind_param('i',$reportId); $stmt->execute(); $res=$stmt->get_result(); while($s=$res->fetch_assoc()){ $s['rows']=[]; $st=$conn->prepare("SELECT * FROM monthly_report_rows WHERE section_id=? ORDER BY urut,id"); $sid=(int)$s['id']; $st->bind_param('i',$sid); $st->execute(); $rr=$st->get_result(); while($r=$rr->fetch_assoc())$s['rows'][]=$r; $st->close(); $out[]=$s; } $stmt->close(); return $out;
}

function lr_save_report(mysqli $conn, int $reportId): void {
    $userId=lr_user_id();
    $pend=lr_post('pendahuluan'); $simp=lr_post('simpulan'); $pen=lr_post('penutup'); $sn=lr_post('signed_name'); $sp=lr_post('signed_position');
    $oldStatus='draft'; $rs=$conn->query("SELECT status FROM monthly_report_headers WHERE id=".(int)$reportId." LIMIT 1"); if($rs && ($r=$rs->fetch_assoc())) $oldStatus=(string)$r['status'];
    $status=isset($_POST['submit_report'])?'submitted':$oldStatus;
    $submitted = isset($_POST['submit_report']) ? ', submitted_at=NOW()' : '';
    $stmt=$conn->prepare("UPDATE monthly_report_headers SET pendahuluan=?, simpulan=?, penutup=?, signed_name=?, signed_position=?, status=?, updated_by=? $submitted WHERE id=?");
    $stmt->bind_param('ssssssii',$pend,$simp,$pen,$sn,$sp,$status,$userId,$reportId); $stmt->execute(); $stmt->close();
    foreach(($_POST['section'] ?? []) as $sid=>$sec){
        $sid=(int)$sid; $intro=(string)($sec['intro_text'] ?? '');
        $stmt=$conn->prepare("UPDATE monthly_report_sections SET intro_text=? WHERE id=? AND report_id=?"); $stmt->bind_param('sii',$intro,$sid,$reportId); $stmt->execute(); $stmt->close();
        // Hapus SEMUA baris (termasuk tarikan) lalu re-insert sesuai isi form.
        // Ini memungkinkan user menghapus baris tarikan yang tidak relevan dari UI.
        $conn->query("DELETE FROM monthly_report_rows WHERE section_id=".$sid);
        $rows=$sec['rows'] ?? [];
        $urut=1;
        foreach($rows as $row){
            $has=false; for($i=1;$i<=10;$i++){ if(trim((string)($row['col'.$i] ?? ''))!=='') $has=true; } if(trim((string)($row['notes'] ?? ''))!=='')$has=true; if(!$has)continue;
            $cols=[]; for($i=1;$i<=10;$i++)$cols[$i]=trim((string)($row['col'.$i] ?? '')); $notes=trim((string)($row['notes'] ?? ''));
            $stmt=$conn->prepare("INSERT INTO monthly_report_rows (section_id,urut,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,notes) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
            $stmt->bind_param('iisssssssssss',$sid,$urut,$cols[1],$cols[2],$cols[3],$cols[4],$cols[5],$cols[6],$cols[7],$cols[8],$cols[9],$cols[10],$notes); $stmt->execute(); $stmt->close(); $urut++;
        }
    }
}

function lr_prefix_source_name(array $cols, string $sourceName): array {
    $new=[]; $new[1]=$sourceName;
    for($i=1;$i<=9;$i++) $new[$i+1]=(string)($cols[$i] ?? '');
    for($i=1;$i<=10;$i++) if(!isset($new[$i])) $new[$i]='';
    return $new;
}

function lr_pull_children(mysqli $conn, int $parentId, string $parentLevel, int $bulan, int $tahun, int $subdivisionId=0, int $divisionId=1): int {
    lr_sync_sections($conn, $parentId, $parentLevel);
    $parentSections=[]; foreach(lr_sections_with_rows($conn,$parentId) as $s){$parentSections[$s['section_code']]=(int)$s['id']; $conn->query("DELETE FROM monthly_report_rows WHERE section_id=".(int)$s['id']." AND source_row_id IS NOT NULL");}
    $conn->query("DELETE FROM monthly_report_sources WHERE parent_report_id=".$parentId);
    $childLevel = $parentLevel==='kasubdiv' ? 'unit' : 'kasubdiv';
    $sql="SELECT h.id,h.report_type,h.report_level,h.unit_id,h.subdivision_id,h.division_id,h.title FROM monthly_report_headers h WHERE h.report_level=? AND h.bulan=? AND h.tahun=?";
    $types='sii'; $vals=[$childLevel,$bulan,$tahun];
    if($parentLevel==='kasubdiv'){ $sql.=" AND h.subdivision_id=?"; $types.='i'; $vals[]=$subdivisionId; }
    else { $sql.=" AND h.division_id=?"; $types.='i'; $vals[]=$divisionId; }
    // Hanya tarik laporan yang sudah dikirim supaya draft unit tidak ikut masuk rekap.
    $sql.=" AND h.status IN ('submitted','reviewed','approved','final') ORDER BY h.report_type,h.unit_id,h.subdivision_id,h.id";
    $stmt=$conn->prepare($sql); $stmt->bind_param($types,...$vals); $stmt->execute(); $res=$stmt->get_result(); $children=[]; while($r=$res->fetch_assoc())$children[]=$r; $stmt->close();
    $copied=0;
    foreach($children as $child){
        $cid=(int)$child['id']; $stmt=$conn->prepare("INSERT IGNORE INTO monthly_report_sources (parent_report_id,child_report_id,source_level) VALUES (?,?,?)"); $sl=$childLevel; $stmt->bind_param('iis',$parentId,$cid,$sl); $stmt->execute(); $stmt->close();
        $sourceName='';
        if($childLevel==='unit' && !empty($child['unit_id'])){ $u=$conn->query("SELECT name FROM units WHERE id=".(int)$child['unit_id'])->fetch_assoc(); $sourceName=(string)($u['name']??''); }
        if($childLevel==='kasubdiv' && !empty($child['subdivision_id'])){ $u=$conn->query("SELECT name FROM nursing_subdivisions WHERE id=".(int)$child['subdivision_id'])->fetch_assoc(); $sourceName=(string)($u['name']??''); }
        if($sourceName==='') $sourceName=(string)($child['title'] ?? '');
        lr_sync_sections($conn, $cid, $childLevel);
        foreach(lr_sections_with_rows($conn,$cid) as $sec){
            $code=$sec['section_code']; if(!isset($parentSections[$code]))continue; $psid=$parentSections[$code];
            $next=(int)($conn->query("SELECT COALESCE(MAX(urut),0)+1 n FROM monthly_report_rows WHERE section_id=$psid")->fetch_assoc()['n']??1);
            foreach($sec['rows'] as $row){
                $old=[]; for($i=1;$i<=10;$i++)$old[$i]=(string)($row['col'.$i] ?? '');
                // Nama unit/kasubdiv SELALU masuk kolom pertama; data asli digeser ke kanan.
                $cols = lr_prefix_source_name($old, $sourceName);
                $notes=(string)($row['notes'] ?? ''); $sourceRowId=(int)$row['id']; $sourceLevel=$childLevel;
                $ins=$conn->prepare("INSERT INTO monthly_report_rows (section_id,urut,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,notes,source_row_id,source_level) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
                $ins->bind_param('iisssssssssssis',$psid,$next,$cols[1],$cols[2],$cols[3],$cols[4],$cols[5],$cols[6],$cols[7],$cols[8],$cols[9],$cols[10],$notes,$sourceRowId,$sourceLevel); $ins->execute(); $ins->close();
                $next++; $copied++;
            }
        }
    }
    return $copied;
}

function lr_current_module(): string {
    $m = trim((string)($_GET['module'] ?? $_POST['module'] ?? 'laporan_bulanan'));
    return $m !== '' ? $m : 'laporan_bulanan';
}

function lr_current_page(string $fallback='unit_form'): string {
    $p = trim((string)($_GET['page'] ?? $_POST['page'] ?? $fallback));
    return $p !== '' ? $p : $fallback;
}


function lr_render_scripts(): void {
    static $rendered = false;
    if ($rendered) return;
    $rendered = true;
?>
<style>
/* Pastikan tombol aksi laporan selalu di atas elemen sticky/fixed lain */
.lr-del-row-btn, .lr-add-row-btn, .lr-clear-tarikan-btn {
    position: relative;
    z-index: 9999 !important;
    pointer-events: auto !important;
}
.lr-del-row-btn:hover { background:#fee2e2 !important; }
</style>
<script>
/* ══════════════════════════════════════════════════════════════
   Laporan Bulanan — Row Management
   Menggunakan EVENT DELEGATION pada document (capture phase, paling awal)
   TANPA inline onclick sama sekali — supaya tidak tergantung apakah
   atribut onclick berhasil di-attach ulang saat elemen di-clone,
   dan supaya event listener kita SELALU yang pertama menerima klik
   sebelum handler global lain (misalnya passcode modal) sempat jalan.
   ══════════════════════════════════════════════════════════════ */
function lrRenumberRows(tbody){
    const rows = tbody.querySelectorAll('tr');
    rows.forEach((tr, idx) => {
        tr.dataset.rowIndex = idx;
        const num = tr.querySelector('.row-number');
        if (num && num.childNodes[0]) num.childNodes[0].nodeValue = String(idx + 1);
        tr.querySelectorAll('textarea').forEach(el => {
            el.name = el.name.replace(/\[rows\]\[\d+\]/, '[rows][' + idx + ']');
        });
    });
}
function lrAddRow(sectionId){
    const tbody = document.querySelector('[data-section-body="' + sectionId + '"]');
    if (!tbody) return;
    const last = tbody.querySelector('tr:last-child');
    if (!last) return;
    const clone = last.cloneNode(true);
    clone.classList.remove('bg-amber-50');
    clone.querySelectorAll('textarea').forEach(el => { el.value=''; el.removeAttribute('readonly'); });
    tbody.appendChild(clone);
    lrRenumberRows(tbody);
}
function lrRemoveRow(tr){
    const tbody = tr ? tr.parentElement : null;
    if (!tr || !tbody) return;
    if (tbody.querySelectorAll('tr').length === 1) {
        tr.querySelectorAll('textarea').forEach(el => el.value='');
        return;
    }
    tr.remove();
    lrRenumberRows(tbody);
}
function lrClearTarikan(sectionId){
    if (!confirm('Bersihkan semua baris tarikan dari seksi ini?')) return;
    const tbody = document.querySelector('[data-section-body="' + sectionId + '"]');
    if (!tbody) return;
    tbody.querySelectorAll('tr').forEach(tr => {
        if (tr.classList.contains('bg-amber-50') || tr.querySelector('[class*="amber"]')) {
            tr.remove();
        }
    });
    lrRenumberRows(tbody);
    if (tbody.querySelectorAll('tr').length === 0) {
        lrAddRow(sectionId);
    }
}

/* ── SATU listener global di document, capture=true, dijalankan paling awal ──
   Pakai data-action attribute, BUKAN onclick, agar:
   1. Tidak bisa di-block oleh keyword filter passcode modal (yang scan onclick attr)
   2. Tetap bekerja walau elemen di-clone (delegation, tidak bind langsung ke elemen)
   3. Selalu menang race-condition karena capture=true didaftarkan paling awal saat load
*/
document.addEventListener('click', function(e) {
    const actionBtn = e.target.closest('[data-action="remove-row"], [data-action="add-row"], [data-action="clear-tarikan"]');
    if (!actionBtn) return;

    /* Hentikan SEGALA propagasi lain (termasuk passcode modal) sebelum diproses */
    e.stopPropagation();
    e.stopImmediatePropagation();
    e.preventDefault();

    const action = actionBtn.dataset.action;
    if (action === 'remove-row') {
        const tr = actionBtn.closest('tr');
        lrRemoveRow(tr);
    } else if (action === 'add-row') {
        lrAddRow(actionBtn.dataset.sectionId);
    } else if (action === 'clear-tarikan') {
        lrClearTarikan(actionBtn.dataset.sectionId);
    }
}, true); /* true = capture phase, dijalankan SEBELUM listener manapun di elemen anak */
</script>
<?php
}

function lr_render_filter(int $bulan, int $tahun, string $extra='', string $pageFallback='unit_form'): void {
    $module = lr_current_module();
    $page = lr_current_page($pageFallback);
?>
<form method="get" action="" class="flex flex-wrap gap-2 items-end bg-white p-4 rounded-2xl border shadow-sm mb-4">
    <input type="hidden" name="module" value="<?= lr_e($module) ?>">
    <input type="hidden" name="page" value="<?= lr_e($page) ?>">
    <label class="text-sm font-semibold">Bulan<br><select name="bulan" class="border rounded-xl p-2"><?php for($i=1;$i<=12;$i++):?><option value="<?= $i ?>" <?= $i===$bulan?'selected':'' ?>><?= lr_e(lr_bulan($i)) ?></option><?php endfor;?></select></label>
    <label class="text-sm font-semibold">Tahun<br><input name="tahun" value="<?= lr_e($tahun) ?>" class="border rounded-xl p-2 w-28"></label>
    <?= $extra ?>
    <button type="submit" class="bg-blue-700 text-white px-4 py-2 rounded-xl font-bold">Tampilkan</button>
</form>
<?php lr_render_scripts(); ?>
<?php }

function lr_report_card_header(array $h): void { ?>
<div class="bg-gradient-to-r from-blue-900 to-cyan-700 text-white rounded-3xl p-6 shadow-lg mb-5">
    <div class="flex flex-wrap justify-between gap-4 items-center">
        <div><div class="text-sm opacity-80">Laporan Bulanan Keperawatan</div><h1 class="text-2xl font-black"><?= lr_e($h['title'] ?? '') ?></h1><div class="mt-1 opacity-90"><?= lr_e(lr_bulan((int)$h['bulan']).' '.(int)$h['tahun']) ?> · Status: <b><?= lr_e(strtoupper((string)$h['status'])) ?></b></div></div>
        <img src="<?= lr_e(lr_logo_url()) ?>" class="h-14 bg-white rounded-2xl p-2" alt="Logo">
    </div>
</div>
<?php }

function lr_render_rows_editor(array $section, array $cols, string $mode='unit'): void {
    $rows=$section['rows'];
    $min=max(count($rows)+1,1);
    $sid=(int)$section['id'];
?>
<div class="overflow-x-auto" style="position:relative;z-index:1;">
<table class="min-w-full text-sm border border-slate-200 rounded-xl overflow-hidden" data-section-table="<?= $sid ?>" style="position:relative;z-index:1;">
<thead><tr class="bg-slate-100 text-slate-700"><th class="p-2 border w-12">No</th><?php foreach($cols as $c):?><th class="p-2 border min-w-[180px]"><?= lr_e($c) ?></th><?php endforeach;?><th class="p-2 border min-w-[180px]">Catatan</th><th class="p-2 border w-20">Aksi</th></tr></thead>
<tbody data-section-body="<?= $sid ?>">
<?php for($r=0;$r<$min;$r++): $row=$rows[$r]??[]; $isTarikan = !empty($row['source_row_id']); ?>
<tr class="<?= $isTarikan?'bg-amber-50':'' ?>" data-row-index="<?= $r ?>" style="position:relative;">
<td class="border p-1 text-center row-number"><?= $r+1 ?><?= $isTarikan?'<div class="text-[10px] text-amber-700 leading-none mt-1">tarikan</div>':'' ?></td>
<?php for($i=1;$i<=count($cols);$i++): ?><td class="border p-1"><textarea name="section[<?= $sid ?>][rows][<?= $r ?>][col<?= $i ?>]" class="w-full min-h-[64px] border-0 focus:ring rounded-lg p-2"><?= lr_e($row['col'.$i] ?? '') ?></textarea></td><?php endfor; ?>
<td class="border p-1"><textarea name="section[<?= $sid ?>][rows][<?= $r ?>][notes]" class="w-full min-h-[64px] border-0 focus:ring rounded-lg p-2"><?= lr_e($row['notes'] ?? '') ?></textarea></td>
<td class="border p-1 text-center" style="position:relative;z-index:2;">
    <button type="button"
            class="lr-del-row-btn"
            data-no-passcode="1"
            data-action="remove-row"
            style="position:relative;z-index:3;pointer-events:auto;color:#dc2626;background:#fff;border:1px solid #fca5a5;cursor:pointer;font-weight:700;font-size:.8rem;padding:4px 10px;border-radius:6px;">✕</button>
</td>
</tr>
<?php endfor; ?>
</tbody></table></div>
<div class="flex flex-wrap gap-2 mt-3">
<button type="button" class="bg-slate-800 text-white px-4 py-2 rounded-xl font-bold text-sm lr-add-row-btn" data-no-passcode="1" data-action="add-row" data-section-id="<?= $sid ?>">+ Tambah Baris</button>
<button type="button" class="px-4 py-2 rounded-xl font-bold text-sm lr-clear-tarikan-btn" style="background:#fee2e2;color:#dc2626;border:1px solid #fca5a5" data-no-passcode="1" data-action="clear-tarikan" data-section-id="<?= $sid ?>" title="Bersihkan semua baris tarikan">🗑 Bersihkan Tarikan</button>
</div>
<?php }

function lr_render_report_form(mysqli $conn, int $reportId, string $mode): void {
    $h=lr_report($conn,$reportId); if(!$h){echo '<div class="p-4 bg-red-50">Laporan tidak ditemukan.</div>';return;} $sections=lr_sections_with_rows($conn,$reportId); lr_report_card_header($h); ?>
<form method="post" class="space-y-5">
<input type="hidden" name="report_id" value="<?= (int)$reportId ?>">
<div class="bg-white rounded-2xl border shadow-sm p-5">
    <h2 class="font-black text-lg mb-3">Identitas & Narasi</h2>
    <label class="block text-sm font-bold mb-1">Pendahuluan</label><textarea name="pendahuluan" class="w-full border rounded-xl p-3 min-h-[110px]" placeholder="Pendahuluan laporan"><?= lr_e($h['pendahuluan'] ?? ($mode==='unit'?'':lr_default_pendahuluan())) ?></textarea>
    <div class="grid md:grid-cols-2 gap-3 mt-3">
        <label class="text-sm font-bold">Nama Penandatangan<br><input name="signed_name" value="<?= lr_e($h['signed_name'] ?? '') ?>" class="w-full border rounded-xl p-3"></label>
        <label class="text-sm font-bold">Jabatan<br><input name="signed_position" value="<?= lr_e($h['signed_position'] ?? '') ?>" class="w-full border rounded-xl p-3"></label>
    </div>
</div>
<?php foreach($sections as $sec): $cols=lr_columns_for_mode((string)$sec['section_code'], $mode); ?>
<div class="bg-white rounded-2xl border shadow-sm p-5">
    <div class="flex justify-between items-center gap-3 mb-3"><h2 class="font-black text-lg"><?= lr_e($sec['section_title']) ?></h2><span class="text-xs px-3 py-1 rounded-full bg-slate-100 text-slate-600"><?= lr_e($sec['section_code']) ?></span></div>
    <label class="block text-sm font-bold mb-1">Narasi / Analisa Bagian Ini</label><textarea name="section[<?= (int)$sec['id'] ?>][intro_text]" class="w-full border rounded-xl p-3 min-h-[80px] mb-3"><?= lr_e($sec['intro_text'] ?? '') ?></textarea>
    <?php lr_render_rows_editor($sec,$cols,$mode); ?>
</div>
<?php endforeach; ?>
<div class="bg-white rounded-2xl border shadow-sm p-5">
    <h2 class="font-black text-lg mb-3">Simpulan, Analisa Akhir, dan Penutup</h2>
    <label class="block text-sm font-bold mb-1">Simpulan / Analisa</label><textarea name="simpulan" class="w-full border rounded-xl p-3 min-h-[120px]"><?= lr_e($h['simpulan'] ?? '') ?></textarea>
    <label class="block text-sm font-bold mt-3 mb-1">Penutup</label><textarea name="penutup" class="w-full border rounded-xl p-3 min-h-[80px]"><?= lr_e($h['penutup'] ?? '') ?></textarea>
</div>
<div class="sticky bottom-3 z-20 flex flex-wrap gap-2 bg-white/95 backdrop-blur p-3 rounded-2xl border shadow-lg">
    <button data-no-passcode="1" name="save_report" value="1" class="bg-emerald-600 text-white px-5 py-3 rounded-xl font-black">💾 Simpan Draft</button>
    <button data-no-passcode="1" name="submit_report" value="1" class="bg-blue-700 text-white px-5 py-3 rounded-xl font-black">📤 Submit Laporan</button>
    <a class="bg-slate-900 text-white px-5 py-3 rounded-xl font-black" href="?module=laporan_bulanan&page=export_word&report_id=<?= (int)$reportId ?>" target="_blank">📄 Export Word</a>
</div>
</form>
<?php lr_render_scripts(); ?>
<?php }
