<?php
declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

ob_start();

header('Content-Type: application/json; charset=utf-8');

function jsonResponse($data, $status = 200): void
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }
    http_response_code($status);
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function jsonError($message, $code = 400): void
{
    jsonResponse(['ok' => false, 'error' => $message], $code);
}

// Cari database.php di berbagai lokasi
$dbPaths = [
    __DIR__ . '/../config/database.php',
    dirname(__DIR__) . '/config/database.php',
    __DIR__ . '/config/database.php',
    __DIR__ . '/../../config/database.php'
];

$dbLoaded = false;
foreach ($dbPaths as $path) {
    if (file_exists($path)) {
        require_once $path;
        $dbLoaded = true;
        break;
    }
}

if (!$dbLoaded) {
    jsonError('Database configuration not found. Checked: ' . implode(', ', $dbPaths), 500);
}

// Session handling
if (session_status() === PHP_SESSION_NONE) {
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => '',
        'httponly' => true,
        'samesite' => 'Lax'
    ]);
    session_start();
}

if (empty($_SESSION) && isset($_COOKIE[session_name()])) {
    session_id($_COOKIE[session_name()]);
    session_start();
}

// Bypass login check untuk sementara (hapus setelah session fix)
$isLoggedIn = true;

if (!$isLoggedIn) {
    // Check session jika tidak bypass
    $sessionKeys = ['user_id', 'employee_id', 'username', 'full_name', 'id', 'nama', 'name', 'user'];
    $hasSession = false;
    foreach ($sessionKeys as $key) {
        if (isset($_SESSION[$key]) && !empty($_SESSION[$key])) {
            $hasSession = true;
            break;
        }
    }
    
    if (!$hasSession && isset($_SESSION['user']) && is_array($_SESSION['user'])) {
        $hasSession = true;
    }
    
    if (!$hasSession) {
        jsonError('Sesi login tidak valid. Silakan login ulang.', 401);
    }
}

if (!function_exists('getConnection')) {
    jsonError('Function getConnection() not found in database.php', 500);
}

$conn = getConnection();

if (!$conn || !($conn instanceof mysqli)) {
    jsonError('Database connection failed', 500);
}

if ($conn->connect_error) {
    jsonError('Database connection error: ' . $conn->connect_error, 500);
}

function currentSessionUserMeta(mysqli $conn): array
{
    $userId = null;
    $employeeId = null;

    $fullName = (string)(
        $_SESSION['full_name']
        ?? $_SESSION['user']['nama']
        ?? $_SESSION['user']['name']
        ?? $_SESSION['user']['full_name']
        ?? $_SESSION['username']
        ?? 'System'
    );

    if (!empty($_SESSION['employee_id'])) {
        $employeeId = (int)$_SESSION['employee_id'];
    } elseif (!empty($_SESSION['user']['employee_id'])) {
        $employeeId = (int)$_SESSION['user']['employee_id'];
    } elseif (!empty($_SESSION['user']['id']) && empty($_SESSION['user_id'])) {
        $employeeId = (int)$_SESSION['user']['id'];
    }

    $candidateUserId = 0;
    if (!empty($_SESSION['user_id'])) {
        $candidateUserId = (int)$_SESSION['user_id'];
    } elseif (!empty($_SESSION['user']['user_id'])) {
        $candidateUserId = (int)$_SESSION['user']['user_id'];
    } elseif (!empty($_SESSION['id'])) {
        $candidateUserId = (int)$_SESSION['id'];
    }

    if ($candidateUserId > 0) {
        $stmt = $conn->prepare("SELECT id FROM users WHERE id = ? LIMIT 1");
        if ($stmt) {
            $stmt->bind_param("i", $candidateUserId);
            $stmt->execute();
            $res = $stmt->get_result();
            if ($res && $res->fetch_assoc()) {
                $userId = $candidateUserId;
            }
            $stmt->close();
        }
    }

    if ($userId === null && $employeeId !== null) {
        $stmt = $conn->prepare("SELECT id FROM users WHERE employee_id = ? LIMIT 1");
        if ($stmt) {
            $stmt->bind_param("i", $employeeId);
            $stmt->execute();
            $res = $stmt->get_result();
            if ($res && $row = $res->fetch_assoc()) {
                $userId = (int)$row['id'];
            }
            $stmt->close();
        }
    }

    return [
        'user_id' => $userId,
        'employee_id' => $employeeId,
        'full_name' => $fullName,
    ];
}

function normalizeDateInput(string $value): ?string
{
    $value = trim($value);
    if ($value === '') return null;

    // Format YYYY-MM-DD
    if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
        return $value;
    }

    // Format DD/MM/YYYY
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $value, $m)) {
        return sprintf('%04d-%02d-%02d', (int)$m[3], (int)$m[2], (int)$m[1]);
    }

    // Format DD-MM-YYYY
    if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/', $value, $m)) {
        return sprintf('%04d-%02d-%02d', (int)$m[3], (int)$m[2], (int)$m[1]);
    }

    // Parse with strtotime
    $timestamp = strtotime($value);
    if ($timestamp !== false) {
        return date('Y-m-d', $timestamp);
    }

    return null;
}

function fetchDoctors(mysqli $conn): array
{
    $rows = [];
    $res = $conn->query("
        SELECT id, doctor_name, poli_name, room_number, wing, schedule_code, practice_days, practice_hours
        FROM polyclinic_doctors
        WHERE is_active = 1
        ORDER BY doctor_name ASC
    ");
    if ($res) {
        while ($row = $res->fetch_assoc()) {
            $rows[] = $row;
        }
    }
    return $rows;
}

function fetchReports(mysqli $conn, int $limit = 50): array
{
    $items = [];
    $res = $conn->query("
        SELECT *
        FROM polyclinic_daily_reports
        ORDER BY tanggal DESC, FIELD(shift,'Pagi','Sore'), id DESC
        LIMIT " . (int)$limit
    );

    if (!$res) {
        return $items;
    }

    while ($row = $res->fetch_assoc()) {
        $reportId = (int)$row['id'];
        $row['kunjunganDokter'] = [];
        $row['dokterTidakPraktek'] = [];

        $q1 = $conn->prepare("
            SELECT doctor_id, doctor_name_snapshot AS nama, jumlah_pasien AS jumlah
            FROM polyclinic_daily_report_visits
            WHERE report_id = ?
            ORDER BY id ASC
        ");
        if ($q1) {
            $q1->bind_param("i", $reportId);
            $q1->execute();
            $r1 = $q1->get_result();
            while ($r1 && $x = $r1->fetch_assoc()) {
                $row['kunjunganDokter'][] = $x;
            }
            $q1->close();
        }

        $q2 = $conn->prepare("
            SELECT doctor_id, doctor_name_snapshot AS nama, keterangan_tanggal AS tanggal
            FROM polyclinic_daily_report_offdays
            WHERE report_id = ?
            ORDER BY id ASC
        ");
        if ($q2) {
            $q2->bind_param("i", $reportId);
            $q2->execute();
            $r2 = $q2->get_result();
            while ($r2 && $x = $r2->fetch_assoc()) {
                $row['dokterTidakPraktek'][] = $x;
            }
            $q2->close();
        }

        $items[] = $row;
    }

    return $items;
}

$action = $_GET['ajax_action'] ?? $_POST['ajax_action'] ?? '';

if ($action === '') {
    jsonError('ajax_action parameter required', 400);
}

try {
    // GET: Get doctors list
    if ($_SERVER['REQUEST_METHOD'] === 'GET' && $action === 'getDoctors') {
        jsonResponse([
            'ok' => true,
            'items' => fetchDoctors($conn)
        ]);
    }
    
    // POST: Add new doctor
    elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && $action === 'addDoctor') {
        $input = json_decode(file_get_contents('php://input'), true) ?: [];

        $doctorName = trim((string)($input['doctor_name'] ?? ''));
        $poliName = trim((string)($input['poli_name'] ?? ''));
        $roomNumber = trim((string)($input['room_number'] ?? ''));
        $wing = trim((string)($input['wing'] ?? ''));
        $scheduleCode = trim((string)($input['schedule_code'] ?? ''));
        $practiceDays = trim((string)($input['practice_days'] ?? ''));
        $practiceHours = trim((string)($input['practice_hours'] ?? ''));

        if ($doctorName === '' || $poliName === '') {
            jsonError('Nama dokter dan nama poli wajib diisi.', 422);
        }

        $stmt = $conn->prepare("
            INSERT INTO polyclinic_doctors
            (room_number, poli_name, wing, schedule_code, doctor_name, practice_days, practice_hours, is_active)
            VALUES (?, ?, ?, ?, ?, ?, ?, 1)
        ");
        
        if (!$stmt) {
            jsonError('Prepare gagal: ' . $conn->error, 500);
        }

        $stmt->bind_param(
            "sssssss",
            $roomNumber,
            $poliName,
            $wing,
            $scheduleCode,
            $doctorName,
            $practiceDays,
            $practiceHours
        );

        if (!$stmt->execute()) {
            $err = $stmt->error;
            $stmt->close();
            jsonError('Gagal tambah dokter: ' . $err, 500);
        }

        $newId = (int)$conn->insert_id;
        $stmt->close();

        jsonResponse([
            'ok' => true,
            'id' => $newId,
            'message' => 'Dokter berhasil ditambahkan.'
        ]);
    }
    
    // GET: List reports
    elseif ($_SERVER['REQUEST_METHOD'] === 'GET' && $action === 'listReports') {
        jsonResponse([
            'ok' => true,
            'items' => fetchReports($conn, 100)
        ]);
    }
    
    // POST: Save report
    elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && $action === 'saveReport') {
        $input = json_decode(file_get_contents('php://input'), true) ?: [];

        $tanggal = normalizeDateInput((string)($input['tanggal'] ?? ''));
        $shift = trim((string)($input['shift'] ?? 'Pagi'));

        if (!$tanggal) {
            jsonError('Tanggal tidak valid. Format harus YYYY-MM-DD', 422);
        }

        if (!in_array($shift, ['Pagi', 'Sore'], true)) {
            jsonError('Shift tidak valid.', 422);
        }

        $kunjunganDokter = is_array($input['kunjunganDokter'] ?? null) ? $input['kunjunganDokter'] : [];
        $dokterTidakPraktek = is_array($input['dokterTidakPraktek'] ?? null) ? $input['dokterTidakPraktek'] : [];

        $pasienKhusus = trim((string)($input['pasienKhusus'] ?? ''));
        $masalah = trim((string)($input['masalah'] ?? ''));
        $inventaris = trim((string)($input['inventaris'] ?? ''));
        $petugasEcho = trim((string)($input['petugasEcho'] ?? ''));
        $petugasTreadmill = trim((string)($input['petugasTreadmill'] ?? ''));
        $petugasEKG = trim((string)($input['petugasEKG'] ?? ''));
        $namaKatim = trim((string)($input['namaKatim'] ?? ''));

        $meta = currentSessionUserMeta($conn);

        $conn->begin_transaction();

        try {
            // Check if report already exists
            $stmtCheck = $conn->prepare("SELECT id FROM polyclinic_daily_reports WHERE tanggal = ? AND shift = ? LIMIT 1");
            $existingId = null;
            if ($stmtCheck) {
                $stmtCheck->bind_param("ss", $tanggal, $shift);
                $stmtCheck->execute();
                $resCheck = $stmtCheck->get_result();
                if ($resCheck && $rowCheck = $resCheck->fetch_assoc()) {
                    $existingId = (int)$rowCheck['id'];
                }
                $stmtCheck->close();
            }

            if ($existingId) {
                // Update existing report
                $stmtUpdate = $conn->prepare("
                    UPDATE polyclinic_daily_reports
                    SET pasien_khusus = ?, masalah = ?, inventaris = ?,
                        petugas_echo = ?, petugas_treadmill = ?, petugas_ekg = ?,
                        nama_katim = ?, created_by_user_id = ?, created_by_employee_id = ?,
                        created_by_name = ?, updated_at = NOW()
                    WHERE id = ?
                ");
                if (!$stmtUpdate) {
                    throw new RuntimeException('Prepare update gagal: ' . $conn->error);
                }

                $stmtUpdate->bind_param(
                    "sssssssissi",
                    $pasienKhusus,
                    $masalah,
                    $inventaris,
                    $petugasEcho,
                    $petugasTreadmill,
                    $petugasEKG,
                    $namaKatim,
                    $meta['user_id'],
                    $meta['employee_id'],
                    $meta['full_name'],
                    $existingId
                );

                if (!$stmtUpdate->execute()) {
                    throw new RuntimeException('Gagal update laporan: ' . $stmtUpdate->error);
                }
                $stmtUpdate->close();

                $reportId = $existingId;

                // Delete old entries
                $conn->query("DELETE FROM polyclinic_daily_report_visits WHERE report_id = " . (int)$reportId);
                $conn->query("DELETE FROM polyclinic_daily_report_offdays WHERE report_id = " . (int)$reportId);
            } else {
                // Insert new report
                $stmtInsert = $conn->prepare("
                    INSERT INTO polyclinic_daily_reports
                    (
                        tanggal, shift, pasien_khusus, masalah, inventaris,
                        petugas_echo, petugas_treadmill, petugas_ekg, nama_katim,
                        created_by_user_id, created_by_employee_id, created_by_name
                    )
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                ");
                if (!$stmtInsert) {
                    throw new RuntimeException('Prepare insert gagal: ' . $conn->error);
                }

                $stmtInsert->bind_param(
                    "sssssssssiss",
                    $tanggal,
                    $shift,
                    $pasienKhusus,
                    $masalah,
                    $inventaris,
                    $petugasEcho,
                    $petugasTreadmill,
                    $petugasEKG,
                    $namaKatim,
                    $meta['user_id'],
                    $meta['employee_id'],
                    $meta['full_name']
                );

                if (!$stmtInsert->execute()) {
                    throw new RuntimeException('Gagal insert laporan: ' . $stmtInsert->error);
                }

                $reportId = (int)$conn->insert_id;
                $stmtInsert->close();
            }

            // Insert doctor visits
            if (!empty($kunjunganDokter)) {
                $stmtVisit = $conn->prepare("
                    INSERT INTO polyclinic_daily_report_visits
                    (report_id, doctor_id, doctor_name_snapshot, jumlah_pasien)
                    VALUES (?, ?, ?, ?)
                ");
                if (!$stmtVisit) {
                    throw new RuntimeException('Prepare visit gagal: ' . $conn->error);
                }

                foreach ($kunjunganDokter as $row) {
                    $doctorId = !empty($row['doctor_id']) ? (int)$row['doctor_id'] : null;
                    $doctorName = trim((string)($row['nama'] ?? ''));
                    $jumlah = (int)($row['jumlah'] ?? 0);

                    if ($doctorName === '') continue;

                    $stmtVisit->bind_param("iisi", $reportId, $doctorId, $doctorName, $jumlah);
                    if (!$stmtVisit->execute()) {
                        throw new RuntimeException('Gagal simpan kunjungan dokter: ' . $stmtVisit->error);
                    }
                }
                $stmtVisit->close();
            }

            // Insert off days
            if (!empty($dokterTidakPraktek)) {
                $stmtOff = $conn->prepare("
                    INSERT INTO polyclinic_daily_report_offdays
                    (report_id, doctor_id, doctor_name_snapshot, keterangan_tanggal)
                    VALUES (?, ?, ?, ?)
                ");
                if (!$stmtOff) {
                    throw new RuntimeException('Prepare offday gagal: ' . $conn->error);
                }

                foreach ($dokterTidakPraktek as $row) {
                    $doctorId = !empty($row['doctor_id']) ? (int)$row['doctor_id'] : null;
                    $doctorName = trim((string)($row['nama'] ?? ''));
                    $ket = trim((string)($row['tanggal'] ?? ''));

                    if ($doctorName === '') continue;

                    $stmtOff->bind_param("iiss", $reportId, $doctorId, $doctorName, $ket);
                    if (!$stmtOff->execute()) {
                        throw new RuntimeException('Gagal simpan dokter tidak praktek: ' . $stmtOff->error);
                    }
                }
                $stmtOff->close();
            }

            $conn->commit();

            jsonResponse([
                'ok' => true,
                'id' => $reportId,
                'message' => 'Laporan berhasil disimpan.'
            ]);
            
        } catch (Throwable $e) {
            $conn->rollback();
            jsonError($e->getMessage(), 500);
        }
    }
    
    else {
        jsonError('Aksi tidak dikenal: ' . $action, 404);
    }
    
} catch (Exception $e) {
    jsonError('Server error: ' . $e->getMessage(), 500);
}