<?php
// pages/approval.php — 인센티브 검토 (자동 동기화 + 특별인원배정 + 대표 상태 관리)
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../config/auth.php';
if (!function_exists('getMenuPerm')) {
    function getMenuPerm($db,$k,$r=null){if(!$r)$r=$_SESSION['user_role']??'staff';try{$s=$db->prepare("SELECT * FROM menu_role_permission WHERE menu_key=? AND role_key=?");$s->execute([$k,$r]);$p=$s->fetch(PDO::FETCH_ASSOC);if($p)return $p;}catch(Exception $e){}if(in_array($r,['sysadmin','ceo']))return['view_scope'=>'all','can_create'=>1,'can_edit'=>1,'can_delete'=>1,'need_ceo_approval'=>0,'need_sysadmin_approval'=>0];if($r==='manager')return['view_scope'=>'team','can_create'=>0,'can_edit'=>0,'can_delete'=>0,'need_ceo_approval'=>0,'need_sysadmin_approval'=>0];return['view_scope'=>'own','can_create'=>1,'can_edit'=>0,'can_delete'=>0,'need_ceo_approval'=>0,'need_sysadmin_approval'=>1];}
}
requireLogin();
$db = (new Database())->getConnection();
$user = currentUser();

// ── 특별인원배정 테이블 ──
$db->exec("CREATE TABLE IF NOT EXISTS incentive_special (
    special_id INT AUTO_INCREMENT PRIMARY KEY,
    staff_id INT NOT NULL,
    sale_month CHAR(7) NOT NULL,
    reason TEXT NOT NULL,
    recommended_by INT NOT NULL,
    recommended_name VARCHAR(50) DEFAULT '',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_special(staff_id, sale_month)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

// ── POST 처리 ──
$postMessage = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    $userRole = $_SESSION['user_role'] ?? 'staff';
    $userStaffId = $user['staff_id'];
    $userName = $user['name'];

    $isTeamLeader = false;
    try { $tlC = $db->prepare("SELECT COUNT(*) FROM teams WHERE leader_staff_id=?"); $tlC->execute([$userStaffId]); $isTeamLeader = $tlC->fetchColumn() > 0; } catch(Exception $e) {}
    $isCeoSys = in_array($userRole, ['ceo','sysadmin']);
    $isManager = $userRole === 'manager';
    $canManage = $isCeoSys || $isManager || $isTeamLeader;

    $db->exec("CREATE TABLE IF NOT EXISTS approval_review_log (
        log_id INT AUTO_INCREMENT PRIMARY KEY, approval_id INT NOT NULL, staff_id INT NOT NULL,
        sale_month VARCHAR(7) DEFAULT '', staff_name VARCHAR(50) DEFAULT '', staff_grade VARCHAR(30) DEFAULT '',
        action_type VARCHAR(20) NOT NULL, old_status VARCHAR(20) DEFAULT '', new_status VARCHAR(20) NOT NULL,
        memo VARCHAR(300) DEFAULT '', changed_by INT NOT NULL, changed_by_name VARCHAR(50) DEFAULT '',
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP)");

    // 특별인원배정
    if ($action === 'special_assign' && $canManage) {
        $spStaffId = (int)($_POST['sp_staff_id'] ?? 0);
        $spMonth = $_POST['sp_month'] ?? '';
        $spReason = trim($_POST['sp_reason'] ?? '');
        if ($spStaffId && $spMonth && $spReason) {
            try {
                $db->prepare("INSERT INTO incentive_special (staff_id, sale_month, reason, recommended_by, recommended_name) VALUES(?,?,?,?,?) ON DUPLICATE KEY UPDATE reason=VALUES(reason), recommended_by=VALUES(recommended_by), recommended_name=VALUES(recommended_name)")
                   ->execute([$spStaffId, $spMonth, $spReason, $userStaffId, $userName]);
                $exists = $db->prepare("SELECT approval_id FROM approval_flow WHERE staff_id=? AND approval_month=?");
                $exists->execute([$spStaffId, $spMonth]);
                if (!$exists->fetch()) {
                    $db->prepare("INSERT INTO approval_flow (staff_id, approval_month, calc_min, calc_max, review_status, approve_status) VALUES(?,?,0,0,'대기','대기')")
                       ->execute([$spStaffId, $spMonth]);
                }
                if (function_exists('writeAudit')) writeAudit($db, 'incentive_special', $db->lastInsertId(), 'CREATE', ['staff_id'=>$spStaffId, 'month'=>$spMonth]);
                header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('특별인원이 배정되었습니다.')); exit;
            } catch(Exception $e) { $postMessage = '오류: ' . $e->getMessage(); }
        }
    }

    // 대표 상태 변경
    if ($action === 'ceo_status' && $isCeoSys) {
        $approvalId = (int)($_POST['approval_id'] ?? 0);
        if ($approvalId) {
            $oldRow = $db->prepare("SELECT af.*, s.name, s.grade FROM approval_flow af JOIN staff s ON af.staff_id=s.staff_id WHERE af.approval_id=?");
            $oldRow->execute([$approvalId]); $old = $oldRow->fetch();
            $newStatus = $_POST['ceo_status'] ?? '대기';
            $finalAmt = (isset($_POST['ceo_final_amount']) && $_POST['ceo_final_amount'] !== '') ? (int)$_POST['ceo_final_amount'] : null;
            $memo = trim($_POST['ceo_memo'] ?? '');
            if ($newStatus !== '승인') $finalAmt = null;
            $db->prepare("UPDATE approval_flow SET approve_status=?, approve_date=NOW(), approve_memo=?, final_amount=? WHERE approval_id=?")
               ->execute([$newStatus, $memo, $finalAmt, $approvalId]);
            if ($old) {
                $db->prepare("INSERT INTO approval_review_log (approval_id,staff_id,sale_month,staff_name,staff_grade,action_type,old_status,new_status,memo,changed_by,changed_by_name) VALUES(?,?,?,?,?,?,?,?,?,?,?)")
                   ->execute([$approvalId,$old['staff_id'],$old['approval_month'],$old['name'],$old['grade'],'대표상태변경',$old['approve_status'],$newStatus,$memo,$userStaffId,$userName]);
                writeAudit($db, 'approval_flow', $approvalId, 'APPROVE', ['status'=>$newStatus,'final_amount'=>$finalAmt,'target'=>$old['name']??''], ['old_status'=>$old['approve_status']]);
            }
            header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('상태가 변경되었습니다.')); exit;
        }
    }

    // 관리자 검토
    if ($action === 'review' && $canManage) {
        $approvalId = (int)($_POST['approval_id'] ?? 0);
        if ($approvalId) {
            $oldRow = $db->prepare("SELECT af.*, s.name, s.grade FROM approval_flow af JOIN staff s ON af.staff_id=s.staff_id WHERE af.approval_id=?");
            $oldRow->execute([$approvalId]); $old = $oldRow->fetch();
            $newStatus = $_POST['review_status'] ?? '대기';
            $memo = trim($_POST['review_memo'] ?? '');
            $db->prepare("UPDATE approval_flow SET reviewer_id=?, review_status=?, review_date=NOW(), review_memo=? WHERE approval_id=?")
               ->execute([$userStaffId, $newStatus, $memo, $approvalId]);
            if ($old) {
                $db->prepare("INSERT INTO approval_review_log (approval_id,staff_id,sale_month,staff_name,staff_grade,action_type,old_status,new_status,memo,changed_by,changed_by_name) VALUES(?,?,?,?,?,?,?,?,?,?,?)")
                   ->execute([$approvalId,$old['staff_id'],$old['approval_month'],$old['name'],$old['grade'],'관리자검토',$old['review_status'],$newStatus,$memo,$userStaffId,$userName]);
                writeAudit($db, 'approval_flow', $approvalId, 'UPDATE', ['review_status'=>$newStatus,'target'=>$old['name']??''], ['old_status'=>$old['review_status']]);
            }
            header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('관리자 검토가 완료되었습니다.')); exit;
        }
    }

    // 특별배정 삭제
    if ($action === 'delete_special' && $canManage) {
        $spId = (int)($_POST['special_id'] ?? 0);
        if ($spId) {
            // 특별배정 정보 조회
            $spRow = $db->prepare("SELECT staff_id, sale_month FROM incentive_special WHERE special_id=?");
            $spRow->execute([$spId]); $sp = $spRow->fetch();
            if ($sp) {
                $db->prepare("DELETE FROM incentive_special WHERE special_id=?")->execute([$spId]);
                writeAudit($db, 'incentive_special', $spId, 'DELETE', ['staff_id'=>$sp['staff_id'],'month'=>$sp['sale_month']]);
                // approval_flow에서도 해당 건 삭제 (자동 동기화로 들어온 게 아닌 경우만)
                $hasEligible = false;
                try { $chk = $db->prepare("SELECT COUNT(*) FROM v_incentive_calc WHERE staff_id=? AND sale_month=? AND eligible='Y'"); $chk->execute([$sp['staff_id'], $sp['sale_month']]); $hasEligible = (bool)$chk->fetchColumn(); } catch(Exception $e) {}
                if (!$hasEligible) {
                    $db->prepare("DELETE FROM approval_flow WHERE staff_id=? AND approval_month=?")->execute([$sp['staff_id'], $sp['sale_month']]);
                }
            }
            header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('특별배정이 삭제되었습니다.')); exit;
        }
    }

    // 검토/승인 이력 삭제
    if ($action === 'delete_log' && $isCeoSys) {
        $logId = (int)($_POST['log_id'] ?? 0);
        if ($logId) {
            $db->prepare("DELETE FROM approval_review_log WHERE log_id=?")->execute([$logId]);
            header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('이력이 삭제되었습니다.')); exit;
        }
    }

    // 검토/승인 이력 전체 삭제
    if ($action === 'delete_all_logs' && $isCeoSys) {
        $db->exec("DELETE FROM approval_review_log");
        header("Location: ".BASE_URL."pages/approval.php?msg=" . urlencode('전체 이력이 삭제되었습니다.')); exit;
    }
}

// ── header ──
require_once __DIR__ . '/../includes/header.php';
$perm = getMenuPerm($db, 'approval', $user['role']);

$isCeoOrSys = in_array($user['role'], ['ceo','sysadmin']);
$isManager = $user['role'] === 'manager';
$isTeamLeader = false;
try { $tlC = $db->prepare("SELECT COUNT(*) FROM teams WHERE leader_staff_id=?"); $tlC->execute([$user['staff_id']]); $isTeamLeader = $tlC->fetchColumn() > 0; } catch(Exception $e) {}
$canManage = $isCeoOrSys || $isManager || $isTeamLeader;

$policyMap = [];
try { $policyMap = $db->query("SELECT rule_key, rule_value FROM policy_rule WHERE rule_key IN ('incentive_min_deals','deal_target_monthly','revenue_target_monthly','profit_target_monthly')")->fetchAll(PDO::FETCH_KEY_PAIR); } catch(Exception $e) {}
$minDeals = (int)($policyMap['incentive_min_deals'] ?? 3);
$policyRevTarget = (int)str_replace(',', '', $policyMap['revenue_target_monthly'] ?? '0');
$policyProfitTarget = (int)str_replace(',', '', $policyMap['profit_target_monthly'] ?? '0');

$db->exec("CREATE TABLE IF NOT EXISTS approval_review_log (
    log_id INT AUTO_INCREMENT PRIMARY KEY, approval_id INT NOT NULL, staff_id INT NOT NULL,
    sale_month VARCHAR(7) DEFAULT '', staff_name VARCHAR(50) DEFAULT '', staff_grade VARCHAR(30) DEFAULT '',
    action_type VARCHAR(20) NOT NULL, old_status VARCHAR(20) DEFAULT '', new_status VARCHAR(20) NOT NULL,
    memo VARCHAR(300) DEFAULT '', changed_by INT NOT NULL, changed_by_name VARCHAR(50) DEFAULT '',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP)");

// ── 인센티브 산출 자동 동기화 ──
try {
    $minDealsPolicy = 3;
    try { $minDealsPolicy = (int)$db->query("SELECT rule_value FROM policy_rule WHERE rule_key='incentive_min_deals'")->fetchColumn() ?: 3; } catch(Exception $e) {}
    
    try {
        $eligible = $db->query("SELECT p.staff_id, p.sale_month, p.total_net_profit, p.grade, p.deal_count,
            COALESCE(ir.min_rate,0) AS min_rate, COALESCE(ir.max_rate,0) AS max_rate
            FROM v_profit_by_person p
            LEFT JOIN incentive_rate ir ON p.grade COLLATE utf8mb4_unicode_ci = ir.grade COLLATE utf8mb4_unicode_ci AND COALESCE(ir.is_active,1)=1
            WHERE p.deal_count >= {$minDealsPolicy} AND p.total_net_profit > 0")->fetchAll();
    } catch(Exception $e) {
        // v_profit_by_person 없으면 sales 직접 조회
        $eligible = $db->query("SELECT s.staff_id, s.sale_month, st.grade,
            COUNT(*) AS deal_count, SUM(s.net_profit) AS total_net_profit,
            COALESCE(ir.min_rate,0) AS min_rate, COALESCE(ir.max_rate,0) AS max_rate
            FROM sales s JOIN staff st ON s.staff_id=st.staff_id
            LEFT JOIN incentive_rate ir ON st.grade COLLATE utf8mb4_unicode_ci = ir.grade COLLATE utf8mb4_unicode_ci AND COALESCE(ir.is_active,1)=1
            WHERE s.stage IN('계약','촬영','방송완료') AND s.confirm_type='확정'
            GROUP BY s.staff_id, s.sale_month, st.grade, ir.min_rate, ir.max_rate
            HAVING deal_count >= {$minDealsPolicy} AND total_net_profit > 0")->fetchAll();
    }
    foreach ($eligible as $el) {
        $cMin = round($el['total_net_profit'] * $el['min_rate']);
        $cMax = round($el['total_net_profit'] * $el['max_rate']);
        $exists = $db->prepare("SELECT approval_id FROM approval_flow WHERE staff_id=? AND approval_month=?");
        $exists->execute([$el['staff_id'], $el['sale_month']]);
        if (!$exists->fetch()) {
            $db->prepare("INSERT INTO approval_flow (staff_id, approval_month, calc_min, calc_max, review_status, approve_status) VALUES(?,?,?,?,?,?)")
               ->execute([$el['staff_id'], $el['sale_month'], $cMin, $cMax, '대기', '대기']);
        } else {
            $db->prepare("UPDATE approval_flow SET calc_min=?, calc_max=? WHERE staff_id=? AND approval_month=?")
               ->execute([$cMin, $cMax, $el['staff_id'], $el['sale_month']]);
        }
    }
    
    // ── 대상에서 빠진 건 삭제 (승인 확정된 건 및 특별배정 건은 유지) ──
    $eligibleKeys = array_map(fn($e) => $e['staff_id'].'|'.$e['sale_month'], $eligible);
    try {
        $allFlows = $db->query("SELECT approval_id, staff_id, approval_month, approve_status, COALESCE(special_reason,'') AS special_reason FROM approval_flow")->fetchAll();
    } catch(Exception $e) {
        $allFlows = $db->query("SELECT approval_id, staff_id, approval_month, approve_status, '' AS special_reason FROM approval_flow")->fetchAll();
    }
    foreach ($allFlows as $af) {
        $key = $af['staff_id'].'|'.$af['approval_month'];
        $isSpecial = !empty($af['special_reason']);
        if (!in_array($key, $eligibleKeys) && $af['approve_status'] !== '승인' && !$isSpecial) {
            $db->prepare("DELETE FROM approval_flow WHERE approval_id=?")->execute([$af['approval_id']]);
        }
    }
} catch(Exception $e) {}

$message = $_GET['msg'] ?? $postMessage;

// ── 필터 ──
$filterMonth = $_GET['month'] ?? '';
$filterApprove = $_GET['approve'] ?? '';
$fYear = $_GET['year'] ?? date('Y');

$sql = "SELECT af.*, st.name AS staff_name, st.grade, st.team,
    rv.name AS reviewer_name,
    isp.special_id, isp.reason AS special_reason, isp.recommended_name,
    ic.deal_count, ic.total_revenue, ic.total_net_profit,
    ir.min_rate, ir.max_rate
FROM approval_flow af
JOIN staff st ON af.staff_id=st.staff_id
LEFT JOIN staff rv ON af.reviewer_id=rv.staff_id
LEFT JOIN incentive_special isp ON af.staff_id=isp.staff_id AND af.approval_month=isp.sale_month
LEFT JOIN v_profit_by_person ic ON af.staff_id=ic.staff_id AND af.approval_month=ic.sale_month
LEFT JOIN incentive_rate ir ON st.grade COLLATE utf8mb4_unicode_ci=ir.grade COLLATE utf8mb4_unicode_ci AND COALESCE(ir.is_active,1)=1
WHERE LEFT(af.approval_month,4) = ?";
$params = [$fYear];
if ($filterMonth) { $sql .= " AND af.approval_month = ?"; $params[] = $filterMonth; }
if ($filterApprove) { $sql .= " AND af.approve_status = ?"; $params[] = $filterApprove; }
$sql .= " ORDER BY af.approval_month DESC, st.name";
try {
    $stmt = $db->prepare($sql); $stmt->execute($params);
    $allApprovals = $stmt->fetchAll();
} catch(Exception $e) {
    // v_profit_by_person 미존재 시 sales 직접 조인
    $sql2 = "SELECT af.*, st.name AS staff_name, st.grade, st.team,
        rv.name AS reviewer_name,
        isp.special_id, isp.reason AS special_reason, isp.recommended_name,
        (SELECT COUNT(*) FROM sales s2 WHERE s2.staff_id=af.staff_id AND s2.sale_month=af.approval_month AND s2.stage IN('계약','촬영','방송완료')) AS deal_count,
        (SELECT SUM(s2.revenue) FROM sales s2 WHERE s2.staff_id=af.staff_id AND s2.sale_month=af.approval_month AND s2.stage IN('계약','촬영','방송완료')) AS total_revenue,
        (SELECT SUM(s2.net_profit) FROM sales s2 WHERE s2.staff_id=af.staff_id AND s2.sale_month=af.approval_month AND s2.stage IN('계약','촬영','방송완료')) AS total_net_profit,
        ir.min_rate, ir.max_rate
    FROM approval_flow af
    JOIN staff st ON af.staff_id=st.staff_id
    LEFT JOIN staff rv ON af.reviewer_id=rv.staff_id
    LEFT JOIN incentive_special isp ON af.staff_id=isp.staff_id AND af.approval_month=isp.sale_month
    LEFT JOIN incentive_rate ir ON st.grade COLLATE utf8mb4_unicode_ci=ir.grade COLLATE utf8mb4_unicode_ci AND COALESCE(ir.is_active,1)=1
    WHERE LEFT(af.approval_month,4) = ?";
    $params2 = [$fYear];
    if ($filterMonth) { $sql2 .= " AND af.approval_month = ?"; $params2[] = $filterMonth; }
    if ($filterApprove) { $sql2 .= " AND af.approve_status = ?"; $params2[] = $filterApprove; }
    $sql2 .= " ORDER BY af.approval_month DESC, st.name";
    $stmt2 = $db->prepare($sql2); $stmt2->execute($params2);
    $allApprovals = $stmt2->fetchAll();
}

$apTotalCnt = count($allApprovals);
$apPerPage = 20; $apPage = max(1,(int)($_GET['ap']??1));
$apTotalPages = max(1, ceil($apTotalCnt / $apPerPage));
$approvals = array_slice($allApprovals, ($apPage-1)*$apPerPage, $apPerPage);

$months = $db->query("SELECT DISTINCT approval_month FROM approval_flow ORDER BY approval_month DESC")->fetchAll(PDO::FETCH_COLUMN);
$apYears = $db->query("SELECT DISTINCT LEFT(approval_month,4) FROM approval_flow ORDER BY 1 DESC")->fetchAll(PDO::FETCH_COLUMN);
if (!$apYears) $apYears = [date('Y')];

$allStaff = $db->query("SELECT s.staff_id, s.name, s.grade, s.team FROM staff s JOIN user_account ua ON s.staff_id=ua.staff_id WHERE ua.is_active=1 AND ua.user_role NOT IN('ceo','sysadmin','manager') ORDER BY s.name")->fetchAll();

$logPage = max(1, (int)($_GET['lp'] ?? 1));
$logPerPage = 20; $logOffset = ($logPage - 1) * $logPerPage;
$logTotal = (int)$db->query("SELECT COUNT(*) FROM approval_review_log")->fetchColumn();
$logTotalPages = max(1, ceil($logTotal / $logPerPage));
$reviewLogs = $db->query("SELECT * FROM approval_review_log ORDER BY log_id DESC LIMIT $logPerPage OFFSET $logOffset")->fetchAll();
?>

<div class="page-header">
    <h2>✅ 인센티브 검토</h2>
    <div class="breadcrumb">인센티브 산출 자동 동기화 → 관리자 검토(1차) → 대표 최종 승인(2차)</div>
</div>

<div class="alert alert-info">
    승인 흐름: <strong>인센티브 산출 대상 자동 갱신</strong> → <strong>관리자 검토(1차)</strong> → <strong>대표 최종 승인(2차)</strong>
    &nbsp;|&nbsp; 최소 성사건수: <strong><?= $minDeals ?>건</strong>
</div>

<?php if ($message): ?><div class="alert alert-success">✓ <?= htmlspecialchars($message) ?></div><?php endif; ?>

<!-- 필터 + 특별인원배정 -->
<div class="card" style="margin-bottom:1rem;padding:0.75rem 1rem;">
    <div style="display:flex;gap:0.75rem;align-items:center;flex-wrap:wrap;">
        <form method="GET" style="display:flex;gap:0.75rem;align-items:center;flex-wrap:wrap;flex:1;">
            <select name="year" onchange="this.form.submit()" class="dash-filter" style="width:7rem;">
                <?php foreach($apYears as $y): ?><option value="<?= $y ?>" <?= $fYear==$y?'selected':'' ?>><?= $y ?>년</option><?php endforeach; ?>
            </select>
            <select name="month" onchange="this.form.submit()" class="dash-filter" style="width:9rem;">
                <option value="">월 전체</option>
                <?php foreach ($months as $m): ?><option value="<?= $m ?>" <?= $filterMonth===$m?'selected':'' ?>><?= $m ?></option><?php endforeach; ?>
            </select>
            <select name="approve" onchange="this.form.submit()" class="dash-filter" style="width:9rem;">
                <option value="">상태 전체</option>
                <option value="대기" <?= $filterApprove==='대기'?'selected':'' ?>>대기</option>
                <option value="승인" <?= $filterApprove==='승인'?'selected':'' ?>>승인</option>
                <option value="보류" <?= $filterApprove==='보류'?'selected':'' ?>>보류</option>
            </select>
        </form>
        <?php if ($canManage): ?>
        <button class="btn btn-primary" style="font-size:14px;padding:0.45rem 0.9rem;" onclick="document.getElementById('specialModal').classList.add('show')">⭐ 특별인원배정</button>
        <?php endif; ?>
    </div>
</div>

<!-- 승인 대상 -->
<div class="card">
    <div class="card-header"><h3>승인 대상 (<?= $apTotalCnt ?>건)</h3></div>
    <div class="table-wrap"><table>
        <thead><tr>
            <th>월</th><th>대상자</th><th>직급</th><th>팀</th>
            <th>건</th><th>매출금액</th><th>순이익</th>
            <th>최소</th><th>최대</th><th>예상금액</th>
            <th>1차 검토</th><th>2차 승인</th><th>확정금액</th><th>사유</th>
        </tr></thead>
        <tbody>
        <?php foreach ($approvals as $a):
            $deals = (int)($a['deal_count'] ?? 0);
            $revenue = (int)($a['total_revenue'] ?? 0);
            $profit = (int)($a['total_net_profit'] ?? 0);
            $minRate = (float)($a['min_rate'] ?? 0);
            $maxRate = (float)($a['max_rate'] ?? 0);
            // min_rate가 0이면 grade로 직접 조회
            if ($minRate == 0 && !empty($a['grade'])) {
                $rt = function_exists('getIncRate') ? getIncRate($db, $a['grade']) : null; if($rt){$minRate=(float)$rt['min_rate'];$maxRate=(float)$rt['max_rate'];}
            }
            $calcMin = (int)($a['calc_min'] ?? 0);
            $calcMax = (int)($a['calc_max'] ?? 0);
            // calc_min이 0이면 순이익 × 요율로 직접 계산
            if ($calcMin == 0 && $profit > 0 && $minRate > 0) $calcMin = round($profit * $minRate);
            if ($calcMax == 0 && $profit > 0 && $maxRate > 0) $calcMax = round($profit * $maxRate);
            // 예상금액도 순이익 기반
            $estMin = $profit > 0 && $minRate > 0 ? round($profit * $minRate) : 0;
            $estMax = $profit > 0 && $maxRate > 0 ? round($profit * $maxRate) : 0;
            $isSpecial = !empty($a['special_reason']);
            $reason = $isSpecial ? $a['special_reason'] : ($a['approve_memo'] ?: ($a['review_memo'] ?: ''));
        ?>
        <tr<?php if($isSpecial): ?> style="background:rgba(var(--accent-rgb),0.05);"<?php endif; ?>>
            <td style="font-size:var(--fs-xs);"><?= $a['approval_month'] ?></td>
            <td>
                <strong><?= htmlspecialchars($a['staff_name']) ?></strong>
                <?php if($isSpecial): ?><div style="font-size:0.65rem;color:var(--accent-text);">⭐ 특별배정 (<?= htmlspecialchars($a['recommended_name']) ?>)</div><?php endif; ?>
            </td>
            <td><span class="badge badge-info" style="font-size:var(--fs-xs);"><?= $a['grade'] ?></span></td>
            <td style="font-size:var(--fs-xs);"><?= htmlspecialchars($a['team']??'') ?></td>
            <td class="font-mono"><?= $deals ?></td>
            <td class="font-mono"><?= number_format($revenue) ?></td>
            <td class="font-mono"><?= number_format($profit) ?></td>
            <td class="font-mono"><?= number_format($calcMin) ?></td>
            <td class="font-mono"><?= number_format($calcMax) ?></td>
            <td class="font-mono" style="color:var(--accent-text);">
                <?php if($estMin > 0): ?><?= number_format($estMin) ?>~<?= number_format($estMax) ?><?php else: ?>-<?php endif; ?>
            </td>
            <td>
                <?php if ($isManager || $isCeoOrSys): ?>
                <button class="btn btn-sm <?= ($a['review_status']??'대기')==='승인'?'btn-success':(($a['review_status']??'대기')==='보류'?'btn-warning':'btn-outline') ?>"
                    style="font-size:var(--fs-xs);padding:0.2rem 0.5rem;cursor:pointer;"
                    onclick="openReviewStatus(<?= $a['approval_id'] ?>,'<?= htmlspecialchars(addslashes($a['staff_name'])) ?>','<?= $a['review_status'] ?? '대기' ?>','<?= htmlspecialchars(addslashes($a['review_memo']??'')) ?>')">
                    <?= $a['review_status'] ?? '대기' ?>
                </button>
                <?php else: ?>
                <span class="badge <?= ($a['review_status']??'대기')==='승인'?'badge-success':(($a['review_status']??'대기')==='보류'?'badge-warning':'badge-gray') ?>"><?= $a['review_status'] ?? '대기' ?></span>
                <?php endif; ?>
            </td>
            <td>
                <?php if ($isCeoOrSys): ?>
                <button class="btn btn-sm <?= $a['approve_status']==='승인'?'btn-success':($a['approve_status']==='보류'?'btn-warning':'btn-outline') ?>"
                    style="font-size:var(--fs-xs);padding:0.2rem 0.5rem;cursor:pointer;"
                    onclick="openCeoStatus(<?= $a['approval_id'] ?>,'<?= htmlspecialchars(addslashes($a['staff_name'])) ?>','<?= $a['approve_status'] ?>',<?= $calcMin ?>,<?= $calcMax ?>,<?= (int)($a['final_amount']??0) ?>,'<?= htmlspecialchars(addslashes($a['approve_memo']??'')) ?>')">
                    <?= $a['approve_status'] ?>
                </button>
                <?php else: ?>
                <span class="badge <?= $a['approve_status']==='승인'?'badge-success':($a['approve_status']==='보류'?'badge-warning':'badge-gray') ?>"><?= $a['approve_status'] ?></span>
                <?php endif; ?>
            </td>
            <td class="font-mono" style="font-weight:<?= $a['final_amount']?'700':'400' ?>;color:<?= $a['final_amount']?'var(--success)':'var(--text-tertiary)' ?>;">
                <?= $a['final_amount'] ? number_format($a['final_amount']) : '-' ?>
            </td>
            <td style="font-size:var(--fs-xs);max-width:10rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="<?= htmlspecialchars($reason) ?>">
                <?= htmlspecialchars($reason ?: '-') ?>
                <?php if($canManage && $isSpecial && $a['special_id']): ?>
                <form method="POST" style="display:inline;" onsubmit="return confirm('특별배정을 삭제하시겠습니까?')">
                    <input type="hidden" name="action" value="delete_special">
                    <input type="hidden" name="special_id" value="<?= $a['special_id'] ?>">
                    <button type="submit" class="btn btn-sm" style="font-size:var(--fs-xs);padding:0.15rem 0.4rem;color:var(--text-tertiary);">🗑️</button>
                </form>
                <?php endif; ?>
            </td>
        </tr>
        <?php endforeach; ?>
        <?php if (empty($approvals)): ?><tr><td colspan="14" style="padding:2rem;color:var(--text-tertiary);">승인 대상이 없습니다.</td></tr><?php endif; ?>
        </tbody>
    </table></div>
    <?php if ($apTotalCnt > 0): ?>
    <div style="display:flex;justify-content:center;align-items:center;gap:0.5rem;padding:1rem;">
        <span style="font-size:var(--fs-xs);color:var(--text-tertiary);">총 <?= $apTotalCnt ?>건 (<?= $apPage ?>/<?= $apTotalPages ?>)</span>
        <?php if ($apTotalPages > 1): ?>
        <?php if ($apPage>1): ?><a href="?<?= http_build_query(array_merge($_GET,['ap'=>$apPage-1])) ?>" class="btn btn-outline" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);">‹</a><?php endif; ?>
        <?php for($p=max(1,$apPage-2);$p<=min($apTotalPages,$apPage+2);$p++): ?>
        <a href="?<?= http_build_query(array_merge($_GET,['ap'=>$p])) ?>" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);border-radius:4px;text-decoration:none;<?= $p===$apPage?'background:var(--accent);color:var(--bg-color);font-weight:700;':'color:var(--text-secondary);' ?>"><?= $p ?></a>
        <?php endfor; ?>
        <?php if ($apPage<$apTotalPages): ?><a href="?<?= http_build_query(array_merge($_GET,['ap'=>$apPage+1])) ?>" class="btn btn-outline" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);">›</a><?php endif; ?>
        <?php endif; ?>
    </div>
    <?php endif; ?>
</div>

<!-- 검토 이력 -->
<div class="card" style="margin-top:1.25rem;">
    <div class="card-header" style="display:flex;justify-content:space-between;align-items:center;">
        <h3>📝 검토/승인 이력 (<?= $logTotal ?>건)</h3>
        <?php if ($isCeoOrSys && $logTotal > 0): ?>
        <form method="POST" style="display:inline;" onsubmit="return confirm('전체 이력을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.')">
            <input type="hidden" name="action" value="delete_all_logs">
            <button type="submit" class="btn btn-sm" style="font-size:var(--fs-xs);padding:0.25rem 0.6rem;color:var(--danger);">🗑️ 전체 삭제</button>
        </form>
        <?php endif; ?>
    </div>
    <?php if ($reviewLogs): ?>
    <div class="table-wrap"><table>
        <thead><tr><th style="width:3rem;">NO</th><th>년월</th><th>대상자</th><th>직급</th><th>구분</th><th>변경</th><th>사유</th><th>처리자</th><th>작성일시</th><?php if($isCeoOrSys): ?><th>삭제</th><?php endif; ?></tr></thead>
        <tbody>
        <?php $logStartNo=$logTotal-$logOffset; foreach ($reviewLogs as $i=>$lg): $no=$logStartNo-$i; ?>
        <tr>
            <td style="color:var(--text-tertiary);font-size:var(--fs-xs);"><?= $no ?></td>
            <td style="font-size:var(--fs-xs);"><?= htmlspecialchars($lg['sale_month']??'') ?></td>
            <td><strong><?= htmlspecialchars($lg['staff_name']??'') ?></strong></td>
            <td><span class="badge badge-info" style="font-size:var(--fs-xs);"><?= htmlspecialchars($lg['staff_grade']??'') ?></span></td>
            <td><span class="badge <?= $lg['action_type']==='대표상태변경'?'badge-success':'badge-info' ?>" style="font-size:var(--fs-xs);"><?= $lg['action_type'] ?></span></td>
            <td style="font-size:var(--fs-xs);"><span class="badge badge-gray" style="font-size:var(--fs-xs);"><?= $lg['old_status'] ?></span> → <span class="badge badge-warning" style="font-size:var(--fs-xs);"><?= $lg['new_status'] ?></span></td>
            <td style="font-size:var(--fs-xs);max-width:12rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="<?= htmlspecialchars($lg['memo']) ?>"><?= htmlspecialchars($lg['memo']?:'-') ?></td>
            <td style="font-size:var(--fs-xs);"><?= htmlspecialchars($lg['changed_by_name']??'') ?></td>
            <td style="font-size:var(--fs-xs);color:var(--text-tertiary);white-space:nowrap;"><?= date('Y-m-d H:i',strtotime($lg['created_at'])) ?></td>
            <?php if($isCeoOrSys): ?>
            <td>
                <form method="POST" style="display:inline;" onsubmit="return confirm('이 이력을 삭제하시겠습니까?')">
                    <input type="hidden" name="action" value="delete_log">
                    <input type="hidden" name="log_id" value="<?= $lg['log_id'] ?>">
                    <button type="submit" class="btn btn-sm" style="font-size:var(--fs-xs);padding:0.15rem 0.4rem;color:var(--text-tertiary);">🗑️</button>
                </form>
            </td>
            <?php endif; ?>
        </tr>
        <?php endforeach; ?>
        </tbody>
    </table></div>
    <?php if ($logTotalPages > 1): ?>
    <div style="display:flex;justify-content:center;align-items:center;gap:0.5rem;padding:0.75rem;">
        <span style="font-size:var(--fs-xs);color:var(--text-tertiary);">총 <?= $logTotal ?>건 (<?= $logPage ?>/<?= $logTotalPages ?>)</span>
        <?php if ($logPage>1): ?><a href="?<?= http_build_query(array_merge($_GET,['lp'=>$logPage-1])) ?>" class="btn btn-outline" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);">‹</a><?php endif; ?>
        <?php for($p=max(1,$logPage-2);$p<=min($logTotalPages,$logPage+2);$p++): ?>
        <a href="?<?= http_build_query(array_merge($_GET,['lp'=>$p])) ?>" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);border-radius:4px;text-decoration:none;<?= $p===$logPage?'background:var(--accent);color:var(--bg-color);font-weight:700;':'color:var(--text-secondary);' ?>"><?= $p ?></a>
        <?php endfor; ?>
        <?php if ($logPage<$logTotalPages): ?><a href="?<?= http_build_query(array_merge($_GET,['lp'=>$logPage+1])) ?>" class="btn btn-outline" style="padding:0.25rem 0.5rem;font-size:var(--fs-xs);">›</a><?php endif; ?>
    </div>
    <?php endif; ?>
    <?php else: ?>
    <div style="padding:2rem;color:var(--text-tertiary);font-size:var(--fs-sm);">검토 이력이 없습니다.</div>
    <?php endif; ?>
</div>

<!-- 모달: 특별인원배정 -->
<div class="modal-overlay" id="specialModal">
    <div class="modal" style="max-width:450px;">
        <div class="modal-header"><h3>⭐ 특별인원배정</h3><button class="modal-close" onclick="document.getElementById('specialModal').classList.remove('show')">&times;</button></div>
        <form method="POST">
            <input type="hidden" name="action" value="special_assign">
            <div class="form-group"><label>대상자 <span class="required">*</span></label>
                <select name="sp_staff_id" required>
                    <option value="">-- 직원 선택 --</option>
                    <?php foreach ($allStaff as $s): ?>
                    <option value="<?= $s['staff_id'] ?>"><?= htmlspecialchars($s['name']) ?> (<?= $s['grade'] ?> / <?= $s['team'] ?>)</option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="form-group"><label>대상 월 <span class="required">*</span></label>
                <input type="month" name="sp_month" required value="<?= date('Y-m') ?>">
            </div>
            <div class="form-group"><label>추천 사유 <span class="required">*</span></label>
                <textarea name="sp_reason" rows="3" required placeholder="특별 배정 사유를 작성해주세요."></textarea>
            </div>
            <div class="alert alert-warning" style="font-size:var(--fs-xs);margin-bottom:0.75rem;">
                ※ 추천자: <strong><?= htmlspecialchars($user['name']) ?></strong> — 사유 작성은 필수입니다.
            </div>
            <button type="submit" class="btn btn-primary" style="width:100%;">배정 등록</button>
        </form>
    </div>
</div>

<!-- 모달: 대표 상태 변경 -->
<!-- 1차 관리자 검토 모달 -->
<div class="modal-overlay" id="reviewStatusModal">
    <div class="modal" style="max-width:400px;">
        <div class="modal-header"><h3>📋 1차 관리자 검토 — <span id="rvName"></span></h3><button class="modal-close" onclick="document.getElementById('reviewStatusModal').classList.remove('show')">&times;</button></div>
        <form method="POST">
            <input type="hidden" name="action" value="manager_review">
            <input type="hidden" name="approval_id" id="rvApprovalId">
            <div style="margin-bottom:0.75rem;">현재 검토 상태: <strong id="rvCurrent"></strong></div>
            <div class="form-group"><label>검토 상태 변경 <span class="required">*</span></label>
                <select name="review_status" id="rvStatusSelect" required>
                    <option value="대기">⏳ 대기</option>
                    <option value="보류">⏸ 보류</option>
                    <option value="승인">✅ 승인</option>
                </select>
            </div>
            <div class="form-group"><label>검토 의견</label>
                <textarea name="review_memo" id="rvMemo" rows="3" placeholder="검토 의견 입력"></textarea>
            </div>
            <button type="submit" class="btn btn-primary" style="width:100%;">검토 저장</button>
        </form>
    </div>
</div>

<script>
function openReviewStatus(id, name, status, memo) {
    document.getElementById('rvApprovalId').value = id;
    document.getElementById('rvName').textContent = name;
    document.getElementById('rvCurrent').textContent = status || '대기';
    document.getElementById('rvStatusSelect').value = status || '대기';
    document.getElementById('rvMemo').value = memo || '';
    document.getElementById('reviewStatusModal').classList.add('show');
}
</script>

<!-- 2차 대표 최종 승인 모달 -->
<div class="modal-overlay" id="ceoStatusModal">
    <div class="modal" style="max-width:450px;">
        <div class="modal-header"><h3>🏛 2차 최종 승인 — <span id="ceoName"></span></h3><button class="modal-close" onclick="document.getElementById('ceoStatusModal').classList.remove('show')">&times;</button></div>
        <form method="POST">
            <input type="hidden" name="action" value="ceo_status">
            <input type="hidden" name="approval_id" id="ceoApprovalId">
            <div class="alert alert-info" style="margin-bottom:0.75rem;">산출 범위: <strong id="ceoRange"></strong></div>
            <div style="margin-bottom:0.75rem;">현재 상태: <strong id="ceoCurrent"></strong></div>
            <div class="form-group"><label>상태 변경 <span class="required">*</span></label>
                <select name="ceo_status" id="ceoStatusSelect" required onchange="toggleCeoFinal()">
                    <option value="대기">⏳ 대기</option>
                    <option value="보류">⏸ 보류</option>
                    <option value="승인">✅ 승인</option>
                </select>
            </div>
            <div class="form-group" id="ceoFinalGroup" style="display:none;"><label>확정 금액</label>
                <input type="text" name="ceo_final_amount" id="ceoFinalAmount" data-money inputmode="numeric" placeholder="확정 금액 입력">
            </div>
            <div class="form-group"><label>사유 <span class="required">*</span></label>
                <textarea name="ceo_memo" id="ceoMemo" rows="3" required placeholder="상태 변경 사유"></textarea>
            </div>
            <button type="submit" class="btn btn-success" style="width:100%;">변경 저장</button>
        </form>
    </div>
</div>

<script>
function openCeoStatus(id, name, status, min, max, finalAmt, memo) {
    document.getElementById('ceoApprovalId').value = id;
    document.getElementById('ceoName').textContent = name;
    var fmt = new Intl.NumberFormat('ko-KR');
    document.getElementById('ceoRange').textContent = fmt.format(min) + ' ~ ' + fmt.format(max) + '원';
    document.getElementById('ceoCurrent').textContent = status;
    document.getElementById('ceoStatusSelect').value = status || '대기';
    document.getElementById('ceoFinalAmount').value = finalAmt ? parseInt(finalAmt).toLocaleString() : '';
    document.getElementById('ceoMemo').value = memo || '';
    toggleCeoFinal();
    document.getElementById('ceoStatusModal').classList.add('show');
}
function toggleCeoFinal() {
    document.getElementById('ceoFinalGroup').style.display = document.getElementById('ceoStatusSelect').value === '승인' ? 'block' : 'none';
}
</script>

<?php require_once __DIR__ . '/../includes/footer.php'; ?>
