<?php
// pages/dashboard.php — 대시보드 (전면 개편)
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../includes/header.php';

$db = (new Database())->getConnection();

// ── 필터 파라미터 ──
$fYear    = $_GET['year'] ?? date('Y');
$fMonth   = $_GET['month'] ?? '';
$fWeek    = $_GET['week'] ?? '';
$fDay     = $_GET['day'] ?? '';
$fStaff   = $_GET['staff_id'] ?? '';

// 정책 목표
try {
    $policyTargets = $db->query("SELECT rule_key, rule_value FROM policy_rule WHERE rule_key IN ('revenue_target_monthly','deal_target_monthly','profit_target_monthly')")->fetchAll(PDO::FETCH_KEY_PAIR);
} catch(Exception $e) { $policyTargets = []; }
$revTargetGlobal = (int)str_replace(',', '', $policyTargets['revenue_target_monthly'] ?? '0');
$profitTargetGlobal = (int)str_replace(',', '', $policyTargets['profit_target_monthly'] ?? '0');
$fGrade   = $_GET['grade'] ?? '';
$fTeam    = $_GET['team'] ?? '';

// 날짜 조건 빌드
$where = "WHERE s.stage IN ('계약','촬영','방송완료')";
$params = [];
// 연도 필터 — sale_month 기준 (일관성), NULL이면 created_at fallback
$where .= " AND LEFT(COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')),4) = ?"; $params[] = $fYear;
if ($fMonth) { $where .= " AND COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')) = ?"; $params[] = $fMonth; }
if ($fDay)   { $where .= " AND COALESCE(s.contract_date, DATE(s.created_at)) = ?"; $params[] = $fDay; }
if ($fWeek && $fMonth) {
    $mStart = $fMonth . '-01';
    $weekStart = date('Y-m-d', strtotime($mStart . ' +' . (($fWeek-1)*7) . ' days'));
    $weekEnd   = date('Y-m-d', strtotime($weekStart . ' +6 days'));
    $where .= " AND COALESCE(s.contract_date, DATE(s.created_at)) BETWEEN ? AND ?";
    $params[] = $weekStart; $params[] = $weekEnd;
}
if ($fStaff) { $where .= " AND s.staff_id = ?"; $params[] = $fStaff; }
if ($fGrade) { $where .= " AND st.grade = ?"; $params[] = $fGrade; }
if ($fTeam)  { $where .= " AND st.team = ?"; $params[] = $fTeam; }

// 파이프라인용 필터 (stage 무관, 전체 파이프라인)
$pipeWhere = "WHERE LEFT(COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')),4) = ?";
$pipeParams = [$fYear];
if ($fMonth) { $pipeWhere .= " AND COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')) = ?"; $pipeParams[] = $fMonth; }
if ($fStaff) { $pipeWhere .= " AND s.staff_id = ?"; $pipeParams[] = $fStaff; }
if ($fTeam)  { $pipeWhere .= " AND st.team = ?"; $pipeParams[] = $fTeam; }
if ($fGrade) { $pipeWhere .= " AND st.grade = ?"; $pipeParams[] = $fGrade; }

$hasFilter = $fMonth || $fWeek || $fDay || $fGrade || $fTeam;

// ── 1. 요약 KPI ──
$stmt = $db->prepare("SELECT
    COALESCE(SUM(s.revenue),0) AS total_revenue,
    COALESCE(SUM(s.net_profit),0) AS total_net_profit,
    COUNT(*) AS total_deals,
    CASE WHEN COUNT(*)>0 THEN ROUND(SUM(s.revenue)/COUNT(*)) ELSE 0 END AS avg_price,
    COUNT(DISTINCT s.staff_id) AS active_sellers
FROM sales s JOIN staff st ON s.staff_id=st.staff_id {$where}");
$stmt->execute($params);
$summary = $stmt->fetch();

// 이전 월 비교 (필터 없을 때)
$prevGrowth = null;
if ($fMonth && !$fWeek && !$fDay) {
    $prevMonth = date('Y-m', strtotime($fMonth . '-01 -1 month'));
    $prev = $db->prepare("SELECT COALESCE(SUM(revenue),0) AS rev FROM sales WHERE stage IN('계약','촬영','방송완료') AND COALESCE(sale_month, DATE_FORMAT(created_at,'%Y-%m'))=?");
    $prev->execute([$prevMonth]);
    $prevRev = $prev->fetch()['rev'];
    if ($prevRev > 0) {
        $prevGrowth = round(($summary['total_revenue'] - $prevRev) / $prevRev * 100, 1);
    }
}

// ── 2. 승인 현황 (역할별 상세) ──
$approval = $db->query("SELECT
    SUM(CASE WHEN approve_status='대기' THEN 1 ELSE 0 END) AS pending,
    SUM(CASE WHEN approve_status='보류' THEN 1 ELSE 0 END) AS hold,
    SUM(CASE WHEN approve_status='승인' THEN 1 ELSE 0 END) AS approved
FROM approval_flow")->fetch();
// 관리자 검토 상세 (incentive_review 기준)
$dIrWait=0;$dIrReview=0;$dIrRequest=0;$dIrApproved=0;$dIrReject=0;$dIrConfirm=0;
try {
    $dIrStats = $db->query("SELECT review_status, COUNT(*) AS cnt FROM incentive_review GROUP BY review_status")->fetchAll();
    foreach($dIrStats as $ds) {
        switch($ds['review_status']) { case '대기': $dIrWait=(int)$ds['cnt']; break; case '검토중': $dIrReview=(int)$ds['cnt']; break; case '승인요청': $dIrRequest=(int)$ds['cnt']; break; case '대표승인': $dIrApproved=(int)$ds['cnt']; break; case '반려': $dIrReject=(int)$ds['cnt']; break; case '확정': $dIrConfirm=(int)$ds['cnt']; break; }
    }
} catch(Exception $e) {}

// ── 3. 파이프라인 (필터 적용) ──
// 빈 stage를 미진행으로 자동 업데이트
try { $db->exec("UPDATE sales SET stage='미진행' WHERE stage IS NULL OR stage=''"); } catch(Exception $e) {}
$pipeStmt = $db->prepare("SELECT CASE WHEN s.stage IS NULL OR s.stage='' THEN '미진행' ELSE s.stage END AS stage, COUNT(*) AS cnt, COALESCE(SUM(s.revenue),0) AS rev
FROM sales s JOIN staff st ON s.staff_id=st.staff_id {$pipeWhere} GROUP BY stage HAVING cnt > 0 ORDER BY FIELD(stage,'미진행','리드','제안','계약','촬영','방송완료')");
$pipeStmt->execute($pipeParams);
$pipeline = $pipeStmt->fetchAll();
$pipeTotal = array_sum(array_column($pipeline, 'cnt'));

// 직급별 파이프라인
$pipeGradeStmt = $db->prepare("SELECT st.grade, COUNT(*) AS cnt, COALESCE(SUM(s.revenue),0) AS rev
FROM sales s JOIN staff st ON s.staff_id=st.staff_id {$pipeWhere} GROUP BY st.grade HAVING cnt > 0 ORDER BY rev DESC");
$pipeGradeStmt->execute($pipeParams);
$pipelineGrade = $pipeGradeStmt->fetchAll();
$pipeGradeTotal = array_sum(array_column($pipelineGrade, 'cnt'));

// ── 4. 월별 매출 추이 ──
$mWhere = "WHERE s.stage IN('계약','촬영','방송완료') AND LEFT(COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')),4) = ?";
$mParams = [$fYear];
if ($fStaff) { $mWhere .= " AND s.staff_id = ?"; $mParams[] = $fStaff; }
if ($fGrade || $fTeam) { $mWhere = str_replace("FROM sales", "FROM sales s JOIN staff st ON s.staff_id=st.staff_id", $mWhere); if ($fGrade) { $mWhere .= " AND st.grade = ?"; $mParams[] = $fGrade; } if ($fTeam) { $mWhere .= " AND st.team = ?"; $mParams[] = $fTeam; } }
$monthly = $db->prepare("SELECT COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')) AS sm, SUM(s.revenue) AS rev, SUM(s.net_profit) AS profit, COUNT(*) AS deals
FROM sales s " . (($fGrade || $fTeam) ? "JOIN staff st ON s.staff_id=st.staff_id " : "") . "WHERE s.stage IN('계약','촬영','방송완료') AND LEFT(COALESCE(s.sale_month, DATE_FORMAT(s.created_at,'%Y-%m')),4) = ?" . ($fStaff ? " AND s.staff_id = ?" : "") . ($fGrade ? " AND st.grade = ?" : "") . ($fTeam ? " AND st.team = ?" : "") . "
GROUP BY sm HAVING rev > 0 ORDER BY sm");
$mP = [$fYear]; if ($fStaff) $mP[] = $fStaff; if ($fGrade) $mP[] = $fGrade; if ($fTeam) $mP[] = $fTeam;
$monthly->execute($mP); $monthly = $monthly->fetchAll();

// ── 5. 팀별 매출 ──
$teamStmt = $db->prepare("SELECT st.team, SUM(s.revenue) AS rev, SUM(s.net_profit) AS profit, COUNT(*) AS deals
FROM sales s JOIN staff st ON s.staff_id=st.staff_id {$where}
GROUP BY st.team HAVING rev > 0 ORDER BY rev DESC");
$teamStmt->execute($params);
$teamData = $teamStmt->fetchAll();

// ── 5-1. 매출 기여도 (관리직 제외) ──
$contribStmt = $db->prepare("SELECT s.staff_id, st.name, st.team, SUM(s.revenue) AS rev, SUM(s.net_profit) AS profit
    FROM sales s JOIN staff st ON s.staff_id=st.staff_id {$where}
    AND NOT EXISTS (SELECT 1 FROM user_account ua WHERE ua.staff_id=st.staff_id AND ua.user_role IN ('ceo','sysadmin','manager'))
    GROUP BY s.staff_id ORDER BY profit DESC");
$contribStmt->execute($params);
$dashContribData = $contribStmt->fetchAll();
$dashContribTotal = array_sum(array_column($dashContribData, 'rev'));

// ── 6. 개인 랭킹 (종합) ──
$rankStmt = $db->prepare("
SELECT
    st.staff_id, st.name, st.grade, st.team,
    SUM(s.revenue) AS total_revenue,
    SUM(s.net_profit) AS total_net_profit,
    COUNT(*) AS deals
FROM sales s JOIN staff st ON s.staff_id=st.staff_id
{$where}
GROUP BY st.staff_id ORDER BY total_revenue DESC LIMIT 10");
$rankStmt->execute($params);
$rankings = $rankStmt->fetchAll();

// KPI, 인센티브, 평가 점수 매핑
$rankEnriched = [];
$minDealsPolicy = 3; try { $minDealsPolicy = (int)$db->query("SELECT rule_value FROM policy_rule WHERE rule_key='incentive_min_deals'")->fetchColumn() ?: 3; } catch(Exception $e) {}
foreach ($rankings as $r) {
    $sid = $r['staff_id'];
    $targetMonth = $fMonth ?: null;

    // 확정 건수 (계약/촬영/방송완료 + 확정)
    $cfmStmt = $db->prepare("SELECT COUNT(*) FROM sales s WHERE s.staff_id=? AND s.stage IN('계약','촬영','방송완료') AND s.confirm_type='확정'" . ($targetMonth ? " AND COALESCE(DATE_FORMAT(s.contract_date,'%Y-%m'),s.sale_month)=?" : ""));
    $targetMonth ? $cfmStmt->execute([$sid, $targetMonth]) : $cfmStmt->execute([$sid]);
    $confirmedDeals = (int)$cfmStmt->fetchColumn();

    // KPI - 필터 월 또는 가장 최근 월
    if ($targetMonth) {
        $kpi = $db->prepare("SELECT target_deals, target_amount FROM kpi_target WHERE staff_id=? AND target_month=?");
        $kpi->execute([$sid, $targetMonth]);
    } else {
        $kpi = $db->prepare("SELECT SUM(target_deals) AS target_deals, SUM(target_amount) AS target_amount FROM kpi_target WHERE staff_id=?");
        $kpi->execute([$sid]);
    }
    $kpiRow = $kpi->fetch();
    // 개인 목표 없으면 정책 기본값
    if (!$kpiRow || (!$kpiRow['target_deals'] && !$kpiRow['target_amount'])) {
        if (!isset($policyTargets)) $policyTargets = $db->query("SELECT rule_key, rule_value FROM policy_rule WHERE rule_key IN ('revenue_target_monthly','deal_target_monthly','profit_target_monthly')")->fetchAll(PDO::FETCH_KEY_PAIR);
        $kpiRow = ['target_deals' => (int)str_replace(',', '', $policyTargets['deal_target_monthly'] ?? '0'), 'target_amount' => (int)str_replace(',', '', $policyTargets['profit_target_monthly'] ?? '0')];
    }
    $kpiDealRate = ($kpiRow && $kpiRow['target_deals'] > 0)
        ? round($confirmedDeals / $kpiRow['target_deals'] * 100, 1) : null;
    $kpiAmtRate = ($kpiRow && $kpiRow['target_amount'] > 0)
        ? round(($r['total_net_profit'] ?? 0) / $kpiRow['target_amount'] * 100, 1) : null;

    // 인센티브 - approval_flow 우선, 없으면 v_incentive_calc에서 대상 여부 확인
    if ($targetMonth) {
        $inc = $db->prepare("SELECT approve_status, final_amount, calc_min, calc_max FROM approval_flow WHERE staff_id=? AND approval_month=?");
        $inc->execute([$sid, $targetMonth]);
    } else {
        $inc = $db->prepare("SELECT approve_status, final_amount, calc_min, calc_max FROM approval_flow WHERE staff_id=? ORDER BY approval_month DESC LIMIT 1");
        $inc->execute([$sid]);
    }
    $incRow = $inc->fetch();

    // approval_flow에 없으면 v_incentive_calc에서 산출 범위 조회
    $incEligible = 'N';
    $incCalcMin = 0;
    $incCalcMax = 0;
    if (!$incRow) {
        try {
            if ($targetMonth) {
                $vic = $db->prepare("SELECT eligible, incentive_min, incentive_max FROM v_incentive_calc WHERE staff_id=? AND sale_month=?");
                $vic->execute([$sid, $targetMonth]);
            } else {
                $vic = $db->prepare("SELECT eligible, incentive_min, incentive_max FROM v_incentive_calc WHERE staff_id=? ORDER BY sale_month DESC LIMIT 1");
                $vic->execute([$sid]);
            }
            $vicRow = $vic->fetch();
            if ($vicRow) {
                $incEligible = $vicRow['eligible'];
                $incCalcMin = (int)$vicRow['incentive_min'];
                $incCalcMax = (int)$vicRow['incentive_max'];
            }
        } catch(Exception $e) {
            // v_incentive_calc 미존재 시 직접 계산
            try {
                $pq = $db->prepare("SELECT p.total_net_profit, p.deal_count, p.grade FROM v_profit_by_person p WHERE p.staff_id=?" . ($targetMonth ? " AND p.sale_month=?" : " ORDER BY p.sale_month DESC LIMIT 1"));
                $targetMonth ? $pq->execute([$sid, $targetMonth]) : $pq->execute([$sid]);
                $pr = $pq->fetch();
                if ($pr) {
                    $minD2 = $minDealsPolicy;
                    $incEligible = ($pr['deal_count'] >= $minD2 && $pr['total_net_profit'] > 0) ? 'Y' : 'N';
                    $irq = $db->prepare("SELECT min_rate, max_rate FROM incentive_rate WHERE grade=? AND is_active=1"); $irq->execute([$pr['grade']]);
                    $irr = $irq->fetch();
                    if ($irr && $pr['total_net_profit'] > 0) { $incCalcMin = round($pr['total_net_profit'] * $irr['min_rate']); $incCalcMax = round($pr['total_net_profit'] * $irr['max_rate']); }
                }
            } catch(Exception $e2) {}
        }
    }

    // 평가 점수 - 필터 월 또는 가장 최근
    if ($targetMonth) {
        $perf = $db->prepare("SELECT
            ROUND(((quant_revenue_rate+quant_deal_rate)/2)*0.6 + (qual_attitude+qual_teamwork+qual_contrib)/30*40, 1) AS total_score
        FROM performance_score WHERE staff_id=? AND eval_month=?");
        $perf->execute([$sid, $targetMonth]);
    } else {
        $perf = $db->prepare("SELECT
            ROUND(((quant_revenue_rate+quant_deal_rate)/2)*0.6 + (qual_attitude+qual_teamwork+qual_contrib)/30*40, 1) AS total_score
        FROM performance_score WHERE staff_id=? ORDER BY eval_month DESC LIMIT 1");
        $perf->execute([$sid]);
    }
    $perfRow = $perf->fetch();

    // 인센티브 산출 연동 (매출%, 건수%)
    $incRateRow = null;
    try {
        if ($targetMonth) {
            $irs = $db->prepare("SELECT deal_count, target_deals, total_revenue, total_net_profit, target_amount, rate_basis FROM v_incentive_calc WHERE staff_id=? AND sale_month=?");
            $irs->execute([$sid, $targetMonth]);
        } else {
            $irs = $db->prepare("SELECT deal_count, target_deals, total_revenue, total_net_profit, target_amount, rate_basis FROM v_incentive_calc WHERE staff_id=? ORDER BY sale_month DESC LIMIT 1");
            $irs->execute([$sid]);
        }
        $incRateRow = $irs->fetch();
    } catch(Exception $e) {}
    $r['inc_deal_pct'] = ($incRateRow && $incRateRow['target_deals'] > 0) ? round($incRateRow['deal_count'] / $incRateRow['target_deals'] * 100, 1) : null;
    $r['inc_rev_pct'] = $profitTargetGlobal > 0 ? round(($r['total_net_profit'] ?? 0) / $profitTargetGlobal * 100, 1) : null;

    $r['kpi_deal_rate'] = $kpiDealRate;
    $r['kpi_amt_rate'] = $kpiAmtRate;
    $r['incentive_status'] = null;
    $r['incentive_amount'] = null;
    // incentive_review에서 상태 확인
    try {
        $irChk = $db->prepare("SELECT review_status, final_amount FROM incentive_review WHERE staff_id=?" . ($targetMonth ? " AND sale_month=?" : " ORDER BY sale_month DESC LIMIT 1"));
        $targetMonth ? $irChk->execute([$sid, $targetMonth]) : $irChk->execute([$sid]);
        $irRow = $irChk->fetch();
        if ($irRow) { $r['incentive_status'] = $irRow['review_status']; $r['incentive_amount'] = $irRow['final_amount']; }
    } catch(Exception $e) {}
    $r['incentive_min'] = $incCalcMin;
    $r['incentive_max'] = $incCalcMax;
    $r['incentive_eligible'] = ($confirmedDeals >= $minDealsPolicy && ($incRateRow['total_net_profit'] ?? 0) > 0) ? 'Y' : $incEligible;
    $r['total_score'] = $perfRow ? $perfRow['total_score'] : null;
    $rankEnriched[] = $r;
}

// ── 7. 팀별 랭킹 ──
$teamRankStmt = $db->prepare("
SELECT st.team,
    SUM(s.revenue) AS total_revenue,
    SUM(s.net_profit) AS total_net_profit,
    COUNT(*) AS deals,
    COUNT(DISTINCT s.staff_id) AS members
FROM sales s JOIN staff st ON s.staff_id=st.staff_id
{$where}
GROUP BY st.team ORDER BY total_revenue DESC LIMIT 5");
$teamRankStmt->execute($params);
$teamRankings = $teamRankStmt->fetchAll();

// 팀별 KPI 달성률
foreach ($teamRankings as &$tr) {
    $teamMembers = (int)$tr['members'] ?: 1;
    // KPI 건수: deal_target_monthly × 팀인원수 대비 팀 총 건수%
    $dealTarget = (int)str_replace(',', '', $policyTargets['deal_target_monthly'] ?? '0') * $teamMembers;
    $tr['kpi_deal_rate'] = ($dealTarget > 0) ? round($tr['deals'] / $dealTarget * 100, 1) : null;
    // KPI 금액: revenue_target_monthly 대비 팀 총 순이익%
    $tr['kpi_amt_rate'] = ($revTargetGlobal > 0) ? round($tr['total_net_profit'] / $revTargetGlobal * 100, 1) : null;
}
unset($tr);

// ── 필터 옵션 데이터 ──
$dashYears = $db->query("SELECT DISTINCT LEFT(COALESCE(sale_month, DATE_FORMAT(created_at,'%Y-%m')),4) AS y FROM sales ORDER BY y DESC")->fetchAll(PDO::FETCH_COLUMN);
if (empty($dashYears)) $dashYears = [date('Y')];
$months = $db->prepare("SELECT DISTINCT COALESCE(sale_month, DATE_FORMAT(created_at,'%Y-%m')) AS sm FROM sales WHERE LEFT(COALESCE(sale_month, DATE_FORMAT(created_at,'%Y-%m')),4)=? ORDER BY sm DESC");
$months->execute([$fYear]); $months = $months->fetchAll(PDO::FETCH_COLUMN);
$staffList = $db->query("SELECT s.staff_id, s.name, s.team FROM staff s JOIN user_account u ON s.staff_id=u.staff_id WHERE s.is_active=1 AND u.user_role NOT IN('ceo','sysadmin','manager') ORDER BY s.team, s.name")->fetchAll();
$grades = $db->query("SELECT grade_name FROM grade_master WHERE is_active=1 AND grade_name NOT IN('대표') ORDER BY sort_order")->fetchAll(PDO::FETCH_COLUMN);
$teams = $db->query("SELECT team_name AS team FROM team_master WHERE is_active=1 AND team_name NOT IN('경영진','경영지원','오너','시스템') ORDER BY team_name")->fetchAll(PDO::FETCH_COLUMN);
?>

<div class="page-header">
    <h2>📊 대시보드</h2>
    <div class="breadcrumb">실시간 경영 현황 · 매출 · KPI · 인센티브</div>
</div>

<!-- ═══ 팀 공지사항 ═══ -->
<?php
$myTeam = $user['team'] ?? '';
$teamNotices = [];
try {
    $db->exec("CREATE TABLE IF NOT EXISTS team_notice (
        notice_id INT AUTO_INCREMENT PRIMARY KEY, team VARCHAR(50) NOT NULL, title VARCHAR(200) NOT NULL,
        content TEXT, is_pinned TINYINT(1) DEFAULT 0, author_id INT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    )");
    if ($myTeam) {
        $tnStmt = $db->prepare("SELECT tn.*, s.name AS author_name FROM team_notice tn LEFT JOIN user_account u ON tn.author_id=u.user_id LEFT JOIN staff s ON u.staff_id=s.staff_id WHERE tn.team=? ORDER BY tn.is_pinned DESC, tn.created_at DESC LIMIT 5");
        $tnStmt->execute([$myTeam]);
        $teamNotices = $tnStmt->fetchAll();
    }
} catch(Exception $e) {}
if ($teamNotices): ?>
<div class="card" style="margin-bottom:1rem;padding:0;">
    <div style="display:flex;justify-content:space-between;align-items:center;padding:0.6rem 1rem;border-bottom:1px solid var(--border);">
        <div style="font-size:var(--fs-sm);font-weight:700;">📢 <?= htmlspecialchars($myTeam) ?> 팀 공지사항</div>
        <a href="<?=BASE_URL?>pages/team_status.php?tab=notice" style="font-size:var(--fs-xs);color:var(--accent);text-decoration:none;">전체보기 →</a>
    </div>
    <?php foreach ($teamNotices as $tn): ?>
    <div style="padding:0.4rem 1rem;border-bottom:1px solid rgba(255,255,255,0.03);display:flex;align-items:center;gap:0.5rem;">
        <?php if ($tn['is_pinned']): ?><span style="font-size:var(--fs-xs);color:var(--accent);">📌</span><?php endif; ?>
        <span style="font-size:var(--fs-xs);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><?= htmlspecialchars($tn['title']) ?></span>
        <span style="font-size:var(--fs-xs);color:var(--text-tertiary);white-space:nowrap;"><?= date('m/d', strtotime($tn['created_at'])) ?></span>
        <span style="font-size:var(--fs-xs);color:var(--text-tertiary);"><?= htmlspecialchars($tn['author_name'] ?? '') ?></span>
    </div>
    <?php endforeach; ?>
</div>
<?php endif; ?>

<!-- ═══ 필터 바 ═══ -->
<div class="card" style="margin-bottom:1rem;padding:0.75rem 1rem;">
    <form method="GET" id="filterForm" style="display:flex;gap:0.75rem;align-items:center;flex-wrap:wrap;">
        <select name="year" onchange="this.form.submit()" class="dash-filter" style="width:7rem;">
            <?php foreach ($dashYears 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 ?>" <?= $fMonth===$m?'selected':'' ?>><?= $m ?></option><?php endforeach; ?>
        </select>
        <select name="week" onchange="this.form.submit()" class="dash-filter" style="width:7rem;">
            <option value="">전체 주</option>
            <?php for($w=1;$w<=5;$w++): ?><option value="<?= $w ?>" <?= $fWeek==$w?'selected':'' ?>><?= $w ?>주차</option><?php endfor; ?>
        </select>
        <select name="grade" onchange="this.form.submit()" class="dash-filter" style="width:7rem;">
            <option value="">직급 전체</option>
            <?php foreach ($grades as $g): ?><option value="<?= $g ?>" <?= $fGrade===$g?'selected':'' ?>><?= $g ?></option><?php endforeach; ?>
        </select>
        <select name="team" onchange="this.form.submit()" class="dash-filter" style="width:9rem;">
            <option value="">팀 전체</option>
            <?php foreach ($teams as $t): ?><option value="<?= $t ?>" <?= $fTeam===$t?'selected':'' ?>><?= $t ?></option><?php endforeach; ?>
        </select>
        <?php if ($hasFilter): ?>
            <a href="dashboard.php" class="btn btn-outline" style="padding:0.375rem 1rem;font-size:var(--fs-xs);">초기화</a>
        <?php endif; ?>
    </form>
</div>

<!-- ═══ KPI 요약 카드 ═══ -->
<div class="stat-grid" style="grid-template-columns:repeat(5,1fr);">
    <div class="stat-card blue">
        <div class="stat-label">총 매출</div>
        <div class="stat-value"><?= number_format($summary['total_revenue']/10000) ?></div>
        <div class="stat-sub">만원
            <?php if ($prevGrowth !== null): ?>
                <span style="color:<?= $prevGrowth>=0?'#2E7D32':'#C62828' ?>;font-weight:700;">
                    <?= $prevGrowth>=0?'▲':'▼' ?> <?= abs($prevGrowth) ?>%
                </span>
            <?php endif; ?>
        </div>
    </div>
    <div class="stat-card green">
        <div class="stat-label">총 순이익</div>
        <div class="stat-value"><?= number_format($summary['total_net_profit']/10000) ?></div>
        <div class="stat-sub">만원</div>
    </div>
    <div class="stat-card yellow">
        <div class="stat-label">성사 건수</div>
        <div class="stat-value"><?= number_format($summary['total_deals']) ?></div>
        <div class="stat-sub">건 (계약 이상)</div>
    </div>
    <div class="stat-card blue">
        <div class="stat-label">평균 계약 단가</div>
        <div class="stat-value"><?= number_format($summary['avg_price']/10000) ?></div>
        <div class="stat-sub">만원/건</div>
    </div>
    <div class="stat-card green">
        <div class="stat-label">조직 현황</div>
        <div class="stat-value"><?= (int)$db->query("SELECT COUNT(*) FROM user_account WHERE is_active=1")->fetchColumn() ?></div>
        <div class="stat-sub">명</div>
    </div>
</div>

<!-- ═══ 차트 영역 ═══ -->
<?php
// 최고/최소 기여자 (개인)
$topContrib = $dashContribData[0] ?? null;
$bottomContrib = count($dashContribData) > 1 ? end($dashContribData) : null;
$topPct = ($topContrib && $revTargetGlobal > 0) ? round(($topContrib['profit']??0) / $revTargetGlobal * 100, 1) : 0;
$bottomPct = ($bottomContrib && $revTargetGlobal > 0) ? round(($bottomContrib['profit']??0) / $revTargetGlobal * 100, 1) : 0;
// 최고/최소 기여 팀
$teamRevTotal = array_sum(array_column($teamData, 'rev'));
$topTeam = $teamData[0] ?? null;
$bottomTeam = count($teamData) > 1 ? end($teamData) : null;
$topTeamPct = ($topTeam && $revTargetGlobal > 0) ? round(($topTeam['profit']??0) / $revTargetGlobal * 100, 1) : 0;
$bottomTeamPct = ($bottomTeam && $revTargetGlobal > 0) ? round(($bottomTeam['profit']??0) / $revTargetGlobal * 100, 1) : 0;
?>
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 2fr;gap:1rem;margin-bottom:1.25rem;align-items:stretch;">
    <!-- 최고/최소 기여자 도넛 (개인) -->
    <div class="card" style="padding:1rem;display:flex;flex-direction:column;gap:0.75rem;">
        <h3 style="margin:0;font-size:var(--fs-sm);">🏆 개인 매출 기여도</h3>
        <?php if ($topContrib): ?>
        <div style="">
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);margin-bottom:0.25rem;">🥇 최고 기여자</div>
            <div style="position:relative;width:120px;height:120px;margin:0 auto;">
                <canvas id="topContribChart"></canvas>
                <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);">
                    <div style="font-size:1rem;font-weight:800;color:#00E676;"><?= $topPct ?>%</div>
                </div>
            </div>
            <div style="font-size:var(--fs-xs);font-weight:700;color:var(--text-primary);margin-top:0.25rem;"><?= htmlspecialchars($topContrib['name']) ?></div>
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">매출 <?= number_format($topContrib['rev']/10000) ?>만 · 순이익 <?= number_format(($topContrib['profit']??0)/10000) ?>만</div>
        </div>
        <?php endif; ?>
        <?php if ($bottomContrib && $bottomContrib['staff_id'] != ($topContrib['staff_id'] ?? 0)): ?>
        <div style="border-top:1px solid var(--border);padding-top:0.5rem;">
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);margin-bottom:0.25rem;">⬇️ 최소 기여자</div>
            <div style="position:relative;width:120px;height:120px;margin:0 auto;">
                <canvas id="bottomContribChart"></canvas>
                <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);">
                    <div style="font-size:1rem;font-weight:800;color:#FF6D00;"><?= $bottomPct ?>%</div>
                </div>
            </div>
            <div style="font-size:var(--fs-xs);font-weight:700;color:var(--text-primary);margin-top:0.25rem;"><?= htmlspecialchars($bottomContrib['name']) ?></div>
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">매출 <?= number_format($bottomContrib['rev']/10000) ?>만 · 순이익 <?= number_format(($bottomContrib['profit']??0)/10000) ?>만</div>
        </div>
        <?php endif; ?>
        <?php if (!$topContrib): ?><div style="padding:2rem;color:var(--text-tertiary);font-size:var(--fs-sm);">데이터 없음</div><?php endif; ?>
    </div>

    <!-- 최고/최소 기여 팀 도넛 -->
    <div class="card" style="padding:1rem;display:flex;flex-direction:column;gap:0.75rem;">
        <h3 style="margin:0;font-size:var(--fs-sm);">🏢 팀 매출 기여도</h3>
        <?php if ($topTeam): ?>
        <div style="">
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);margin-bottom:0.25rem;">🥇 최대 기여 팀</div>
            <div style="position:relative;width:120px;height:120px;margin:0 auto;">
                <canvas id="topTeamChart"></canvas>
                <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);">
                    <div style="font-size:1rem;font-weight:800;color:#2979FF;"><?= $topTeamPct ?>%</div>
                </div>
            </div>
            <div style="font-size:var(--fs-xs);font-weight:700;color:var(--text-primary);margin-top:0.25rem;"><?= htmlspecialchars($topTeam['team']) ?></div>
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">매출 <?= number_format($topTeam['rev']/10000) ?>만 · 순이익 <?= number_format(($topTeam['profit']??0)/10000) ?>만</div>
        </div>
        <?php endif; ?>
        <?php if ($bottomTeam && $bottomTeam['team'] != ($topTeam['team'] ?? '')): ?>
        <div style="border-top:1px solid var(--border);padding-top:0.5rem;">
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);margin-bottom:0.25rem;">⬇️ 최소 기여 팀</div>
            <div style="position:relative;width:120px;height:120px;margin:0 auto;">
                <canvas id="bottomTeamChart"></canvas>
                <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);">
                    <div style="font-size:1rem;font-weight:800;color:#AA00FF;"><?= $bottomTeamPct ?>%</div>
                </div>
            </div>
            <div style="font-size:var(--fs-xs);font-weight:700;color:var(--text-primary);margin-top:0.25rem;"><?= htmlspecialchars($bottomTeam['team']) ?></div>
            <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">매출 <?= number_format($bottomTeam['rev']/10000) ?>만 · 순이익 <?= number_format(($bottomTeam['profit']??0)/10000) ?>만</div>
        </div>
        <?php endif; ?>
        <?php if (!$topTeam): ?><div style="padding:2rem;color:var(--text-tertiary);font-size:var(--fs-sm);">데이터 없음</div><?php endif; ?>
    </div>
    <!-- 영업단계&직급별 현황 -->
    <div class="card" style="padding:1rem;display:flex;flex-direction:column;">
        <div style="display:flex;align-items:center;gap:0.5rem;margin-bottom:0.75rem;">
            <?php if ($fGrade): ?>
            <h3 style="margin:0;font-size:var(--fs-sm);">🔄 영업단계 현황</h3>
            <?php else: ?>
            <h3 style="margin:0;font-size:var(--fs-sm);">🔄 영업단계&직급별 현황</h3>
            <div style="display:flex;gap:0.25rem;margin-left:auto;">
                <button onclick="showPipeTab('stage')" id="pipeTabStage" style="font-size:var(--fs-xs);padding:0.15rem 0.4rem;border-radius:4px;border:1px solid var(--border);background:var(--accent);color:var(--bg-color);cursor:pointer;transition:all 0.3s;">영업단계</button>
                <button onclick="showPipeTab('grade')" id="pipeTabGrade" style="font-size:var(--fs-xs);padding:0.15rem 0.4rem;border-radius:4px;border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer;transition:all 0.3s;">직급별</button>
            </div>
            <?php endif; ?>
        </div>
        <div style="position:relative;flex:1;min-height:200px;">
            <div id="pipeStageWrap" style="position:absolute;top:0;left:0;right:0;bottom:0;opacity:1;transition:opacity 0.35s ease;"><canvas id="pipelineChart"></canvas></div>
            <?php if (!$fGrade): ?>
            <div id="pipeGradeWrap" style="position:absolute;top:0;left:0;right:0;bottom:0;opacity:0;pointer-events:none;transition:opacity 0.35s ease;"><canvas id="pipelineGradeChart"></canvas></div>
            <?php endif; ?>
        </div>
    </div>
    <!-- 매출 기여도 (관리직 제외) -->
    <div class="card" style="padding:1rem;display:flex;flex-direction:column;">
        <h3 style="margin:0 0 0.75rem;font-size:var(--fs-sm);">📊 매출 기여도 순위</h3>
        <?php if ($dashContribData): ?>
        <div style="overflow-y:auto;flex:1;">
            <?php foreach(array_slice($dashContribData, 0, 15) as $i => $cd):
                $pct = $revTargetGlobal > 0 ? round(($cd['profit']??0) / $revTargetGlobal * 100, 1) : 0;
            ?>
            <div style="display:flex;align-items:center;gap:0.6rem;margin-bottom:0.85rem;font-size:var(--fs-xs);height:1.3rem;white-space:nowrap;overflow:hidden;">
                <span style="width:1.2rem;color:var(--text-tertiary);font-weight:700;flex-shrink:0;"><?= $i+1 ?></span>
                <span style="width:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;flex-shrink:0;"><?= htmlspecialchars($cd['name']) ?></span>
                <span style="width:5.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-tertiary);font-size:var(--fs-xs);flex-shrink:0;"><?= htmlspecialchars($cd['team']) ?></span>
                <div style="flex:1;height:0.4rem;background:var(--border);border-radius:2px;overflow:hidden;">
                    <div style="height:100%;width:<?= min($pct*2,100) ?>%;background:var(--accent);border-radius:2px;"></div>
                </div>
                <span style="width:2.8rem;font-weight:700;color:var(--accent-text);flex-shrink:0;"><?= $pct ?>%</span>
                <span style="width:4.5rem;color:var(--text-tertiary);font-size:var(--fs-xs);flex-shrink:0;" class="font-mono"><?= number_format(($cd['profit']??0)/10000) ?>만</span>
            </div>
            <?php endforeach; ?>
        </div>
        <?php else: ?><div style="padding:2rem;color:var(--text-tertiary);font-size:var(--fs-sm);">데이터 없음</div><?php endif; ?>
    </div>
</div>

<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem;margin-bottom:1.25rem;">
    <!-- 월별 매출/순이익 추이 -->
    <div class="card" style="padding:1rem;">
        <h3 style="margin:0 0 0.75rem;font-size:var(--fs-sm);">📈 매출·순이익 추이</h3>
        <div style="position:relative;height:200px;"><canvas id="monthlyChart"></canvas></div>
    </div>
    <!-- 팀별 매출 바 차트 -->
    <div class="card" style="padding:1rem;">
        <h3 style="margin:0 0 0.75rem;font-size:var(--fs-sm);">🏢 팀별 매출 비교</h3>
        <div style="position:relative;height:160px;"><canvas id="teamChart"></canvas></div>
    </div>
    <!-- 승인 현황 -->
    <div class="card" style="padding:1rem;">
        <h3 style="margin:0 0 0.75rem;font-size:var(--fs-sm);">✅ 인센티브 지급 검토 현황</h3>
        <div style="display:flex;gap:0;margin-bottom:0.75rem;border-bottom:2px solid var(--border);">
            <button class="dash-review-tab active" onclick="switchReviewTab('mgr',this)" style="flex:1;padding:0.4rem;font-size:var(--fs-xs);font-weight:700;border:none;background:none;cursor:pointer;border-bottom:2px solid var(--accent);margin-bottom:-2px;color:var(--accent-text);">📋 1차 검토</button>
            <button class="dash-review-tab" onclick="switchReviewTab('ceo',this)" style="flex:1;padding:0.4rem;font-size:var(--fs-xs);font-weight:700;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;color:var(--text-tertiary);">🏛 2차 승인</button>
        </div>
        <div id="dashReviewMgr" style="margin-bottom:0.5rem;">
            <div style="display:flex;gap:0.75rem;justify-content:center;align-items:center;padding:0.5rem 0;flex-wrap:wrap;">
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=대기" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:rgba(255,255,255,0.45);"><?= $dIrWait ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">⏳ 대기</div>
                </a>
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=검토중" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:var(--info);"><?= $dIrReview ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">🔍 검토중</div>
                </a>
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=반려" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:var(--danger);"><?= $dIrReject ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">❌ 반려</div>
                </a>
            </div>
        </div>
        <div id="dashReviewCeo" style="display:none;margin-bottom:0.5rem;">
            <div style="display:flex;gap:0.75rem;justify-content:center;align-items:center;padding:0.5rem 0;flex-wrap:wrap;">
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=승인요청" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:var(--warning);"><?= $dIrRequest ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">📋 승인요청</div>
                </a>
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=대표승인" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:var(--success);"><?= $dIrApproved ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">✅ 대표승인</div>
                </a>
                <a href="<?=BASE_URL?>pages/incentive.php?review_st=확정" style="text-decoration:none;text-align:center;">
                    <div style="font-size:1.75rem;font-weight:800;color:#00E676;"><?= $dIrConfirm ?></div>
                    <div style="font-size:var(--fs-xs);color:var(--text-tertiary);">💰 확정</div>
                </a>
            </div>
        </div>
        <script>
        function switchReviewTab(tab, btn) {
            document.getElementById('dashReviewMgr').style.display = tab==='mgr' ? '' : 'none';
            document.getElementById('dashReviewCeo').style.display = tab==='ceo' ? '' : 'none';
            document.querySelectorAll('.dash-review-tab').forEach(b => { b.style.borderBottomColor = 'transparent'; b.style.color = 'var(--text-tertiary)'; });
            btn.style.borderBottomColor = 'var(--accent)'; btn.style.color = 'var(--accent-text)';
        }
        </script>
        <div style="position:relative;height:80px;"><canvas id="approvalChart"></canvas></div>
    </div>
</div>

<!-- ═══ 팀별 랭킹 ═══ -->
<div class="card" style="margin-bottom:1.25rem;">
    <div class="card-header"><h3>🏢 팀별 랭킹</h3></div>
    <div class="table-wrap">
        <table>
            <thead><tr>
                <th>순위</th><th>팀</th><th>매출 합계</th><th>순이익</th><th>건수</th><th>인원</th><th>인당 매출</th><th>KPI 건수달성</th><th>KPI 금액달성</th>
            </tr></thead>
            <tbody>
                <?php foreach ($teamRankings as $i => $tr): ?>
                <tr>
                    <td><strong style="color:<?= $i<3?'#C00000':'#333' ?>;font-size:<?= $i<3?'1.125rem':'0.875rem' ?>;">
                        <?= $i===0?'🥇':($i===1?'🥈':($i===2?'🥉':($i+1))) ?>
                    </strong></td>
                    <td><strong><?= htmlspecialchars($tr['team']) ?></strong></td>
                    <td class="text-right font-mono"><?= number_format($tr['total_revenue']) ?></td>
                    <td class="text-right font-mono"><?= number_format($tr['total_net_profit']) ?></td>
                    <td class="text-center"><?= $tr['deals'] ?></td>
                    <td class="text-center"><?= $tr['members'] ?></td>
                    <td class="text-right font-mono"><?= $tr['members']>0 ? number_format(round($tr['total_revenue']/$tr['members'])) : '-' ?></td>
                    <td class="text-center">
                        <?php if ($tr['kpi_deal_rate'] !== null): ?>
                            <span class="badge <?= $tr['kpi_deal_rate']>=100?'badge-success':($tr['kpi_deal_rate']>=50?'badge-warning':'badge-danger') ?>">
                                <?= $tr['kpi_deal_rate'] ?>%
                            </span>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                    <td class="text-center">
                        <?php if ($tr['kpi_amt_rate'] !== null): ?>
                            <span class="badge <?= $tr['kpi_amt_rate']>=100?'badge-success':($tr['kpi_amt_rate']>=50?'badge-warning':'badge-danger') ?>">
                                <?= $tr['kpi_amt_rate'] ?>%
                            </span>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                </tr>
                <?php endforeach; ?>
                <?php if (empty($teamRankings)): ?>
                <tr><td colspan="9" style="padding:2rem;color:var(--text-tertiary);">데이터가 존재하지 않습니다.</td></tr>
                <?php endif; ?>
            </tbody>
        </table>
    </div>
</div>

<!-- ═══ 개인 종합 랭킹 ═══ -->
<div class="card">
    <div class="card-header"><h3>🏆 랭킹 현황</h3></div>
    <div class="table-wrap">
        <table style="font-size:var(--fs-xs);">
            <thead><tr>
                <th style="width:3rem;">순위</th><th>이름</th><th>직급</th><th>팀</th>
                <th style="">매출</th><th style="">순이익</th><th style="">건수</th>
                <th style="">매출%</th><th style="">건수%</th>
                <th style="">인센티브</th><th style="">인센티브 금액</th>
                <th style="">종합점수</th>
            </tr></thead>
            <tbody>
                <?php foreach ($rankEnriched as $i => $r): ?>
                <tr>
                    <td><strong style="color:<?= $i<3?'#C00000':'#333' ?>;font-size:<?= $i<3?'1.125rem':'0.875rem' ?>;">
                        <?= $i===0?'🥇':($i===1?'🥈':($i===2?'🥉':($i+1))) ?>
                    </strong></td>
                    <td><strong><?= htmlspecialchars($r['name']) ?></strong></td>
                    <td><span class="badge badge-info"><?= $r['grade'] ?></span></td>
                    <td><?= htmlspecialchars($r['team']) ?></td>
                    <td class="text-right font-mono" style="font-size:0.75rem;"><?= number_format($r['total_revenue']) ?></td>
                    <td class="text-right font-mono" style="font-size:0.75rem;"><?= number_format($r['total_net_profit']) ?></td>
                    <td class="text-center"><?= $r['deals'] ?></td>
                    <td class="text-center">
                        <?php if ($r['inc_rev_pct'] !== null): ?>
                            <span class="badge <?= $r['inc_rev_pct']>=100?'badge-success':($r['inc_rev_pct']>=50?'badge-warning':'badge-danger') ?>">
                                <?= $r['inc_rev_pct'] ?>%
                            </span>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                    <td class="text-center">
                        <?php if ($r['inc_deal_pct'] !== null): ?>
                            <span class="badge <?= $r['inc_deal_pct']>=100?'badge-success':($r['inc_deal_pct']>=50?'badge-warning':'badge-danger') ?>">
                                <?= $r['inc_deal_pct'] ?>%
                            </span>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                    <td class="text-center">
                        <?php if ($r['incentive_status']): ?>
                            <?php if ($r['incentive_status']==='승인'): ?>
                                <span class="badge badge-success">✅ 지급</span>
                            <?php elseif ($r['incentive_status']==='보류'): ?>
                                <span class="badge badge-warning">⚠ 보류</span>
                            <?php else: ?>
                                <span class="badge badge-gray">⏳ 대기</span>
                            <?php endif; ?>
                        <?php elseif (($r['incentive_eligible'] ?? 'N') === 'Y'): ?>
                            <span class="badge badge-info">💎 대상</span>
                        <?php else: ?>
                            <span style="color:var(--text-tertiary);font-size:0.6875rem;">❌ 제외</span>
                        <?php endif; ?>
                    </td>
                    <td class="text-right font-mono" style="font-size:0.75rem;">
                        <?php if ($r['incentive_amount']): ?>
                            <strong style="color:var(--success);"><?= number_format($r['incentive_amount']) ?></strong>
                        <?php elseif ($r['incentive_min']): ?>
                            <span style="color:var(--text-tertiary);font-size:0.6875rem;"><?= number_format($r['incentive_min']) ?>~<?= number_format($r['incentive_max']) ?></span>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                    <td class="text-center">
                        <?php if ($r['total_score'] !== null): ?>
                            <strong style="color:<?= $r['total_score']>=70?'#2E7D32':($r['total_score']>=50?'#F57F17':'#C62828') ?>;">
                                <?= $r['total_score'] ?>
                            </strong>
                        <?php else: ?>-<?php endif; ?>
                    </td>
                </tr>
                <?php endforeach; ?>
                <?php if (empty($rankEnriched)): ?>
                <tr><td colspan="12" style="padding:2rem;color:var(--text-tertiary);">데이터가 존재하지 않습니다.</td></tr>
                <?php endif; ?>
            </tbody>
        </table>
    </div>
    <div style="padding:0.5rem;display:flex;justify-content:center;"><a href="<?=BASE_URL?>pages/incentive.php" title="더보기" style="display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:50%;border:none;background:var(--accent);color:var(--bg-color);text-decoration:none;font-weight:400;transition:opacity 0.2s;" onmouseover="this.style.opacity='0.8'" onmouseout="this.style.opacity='1'"><span style="font-size:1.75rem;line-height:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:0;">+</span></a></div>
</div>

<!-- Chart.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script>
// 공통 설정
Chart.defaults.font.family = "'Noto Sans KR', sans-serif";
Chart.defaults.font.size = 12;
Chart.defaults.color = 'rgba(255,255,255,0.55)';
Chart.defaults.borderColor = 'rgba(255,255,255,0.06)';

// 수치 표시 플러그인
const dataLabelPlugin = {
    id: 'dataLabels',
    afterDatasetsDraw(chart) {
        const ctx = chart.ctx;
        chart.data.datasets.forEach((dataset, di) => {
            const meta = chart.getDatasetMeta(di);
            if (!meta.hidden) meta.data.forEach((el, i) => {
                const val = dataset.data[i];
                if (val === 0 || val === null) return;
                ctx.save();
                ctx.font = 'bold 10px sans-serif';
                ctx.fillStyle = '#fff';
                ctx.textAlign = 'center';
                if (chart.config.type === 'doughnut' || chart.config.type === 'pie') {
                    const {x, y} = el.tooltipPosition(); ctx.fillText(val, x, y);
                } else {
                    const label = val >= 100000000 ? (val/100000000).toFixed(1) + '억' : val >= 10000 ? Math.round(val/10000).toLocaleString() + '만' : val.toLocaleString();
                    ctx.fillText(label, el.x, el.y - 8);
                }
                ctx.restore();
            });
        });
    }
};
Chart.register(dataLabelPlugin);

// ── 1. 월별 매출/순이익 추이 (Bar + Line) ──
new Chart(document.getElementById('monthlyChart'), {
    type: 'bar',
    data: {
        labels: <?= json_encode(array_column($monthly, 'sm')) ?>,
        datasets: [
            {
                label: '매출',
                data: <?= json_encode(array_map(fn($m)=>(int)$m['rev'], $monthly)) ?>,
                backgroundColor: 'rgba(255,82,82,0.7)',
                borderColor: '#FF5252',
                borderWidth: 1,
                borderRadius: 6,
                order: 2
            },
            {
                label: '순이익',
                data: <?= json_encode(array_map(fn($m)=>(int)$m['profit'], $monthly)) ?>,
                type: 'line',
                borderColor: '#00E676',
                backgroundColor: 'rgba(0,230,118,0.08)',
                fill: true,
                tension: 0.4,
                pointRadius: 5,
                pointBackgroundColor: '#00E676',
                pointBorderColor: '#111',
                pointBorderWidth: 2,
                order: 1
            },
            <?php if ($revTargetGlobal > 0):
                $totalStaffDash = (int)$db->query("SELECT COUNT(*) FROM staff WHERE 1=1")->fetchColumn() ?: 1;
                $chartTarget = $revTargetGlobal * $totalStaffDash;
            ?>
            {
                label: '매출 목표 (<?= $totalStaffDash ?>명)',
                data: Array(<?= count($monthly) ?>).fill(<?= $chartTarget ?>),
                type: 'line',
                borderColor: 'rgba(255,215,0,0.5)',
                borderDash: [6, 4],
                borderWidth: 2,
                pointRadius: 0,
                fill: false,
                order: 0
            }
            <?php endif; ?>
        ]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { position: 'top', labels: { color: 'rgba(255,255,255,0.7)', padding: 16 } } },
        scales: {
            y: { 
                ticks: { callback: v => (v/10000).toLocaleString('ko-KR') + '만', color: 'rgba(255,255,255,0.5)' }, 
                grid: { color: 'rgba(255,255,255,0.04)' }, 
                beginAtZero: true,
                <?php 
                    $maxRev = max(array_map(fn($m)=>(int)$m['rev'], $monthly) ?: [0]);
                    $yTarget = $revTargetGlobal > 0 ? $revTargetGlobal : 0;
                    if ($yTarget > 0 && $maxRev <= $yTarget): ?>
                max: <?= $yTarget ?>,
                <?php endif; ?>
            },
            x: { ticks: { color: 'rgba(255,255,255,0.5)' }, grid: { color: 'rgba(255,255,255,0.04)' } }
        }
    }
});

// ── 1-1. 최고/최소 기여자 도넛 ──
function makeContribDonut(canvasId, pct, mainColor, bgColor) {
    var el = document.getElementById(canvasId);
    if (!el) return;
    new Chart(el, {
        type: 'doughnut',
        data: {
            labels: ['기여', '기타'],
            datasets: [{ data: [pct, Math.round((100 - pct)*10)/10], backgroundColor: [mainColor, bgColor], borderWidth: 0, hoverOffset: 4 }]
        },
        options: {
            cutout: '70%', responsive: true, maintainAspectRatio: true,
            plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(c) { return c.label + ': ' + c.parsed + '%'; } } } }
        }
    });
}
makeContribDonut('topContribChart', <?= $topPct ?>, '#00E676', 'rgba(255,255,255,0.06)');
makeContribDonut('bottomContribChart', <?= $bottomPct ?>, '#FF6D00', 'rgba(255,255,255,0.06)');
makeContribDonut('topTeamChart', <?= $topTeamPct ?>, '#2979FF', 'rgba(255,255,255,0.06)');
makeContribDonut('bottomTeamChart', <?= $bottomTeamPct ?>, '#AA00FF', 'rgba(255,255,255,0.06)');

// ── 2. 파이프라인 도넛 ──
var pipeTotal = <?= $pipeTotal ?>;
var pipeStageChart = new Chart(document.getElementById('pipelineChart'), {
    type: 'doughnut',
    data: {
        labels: <?= json_encode(array_column($pipeline, 'stage')) ?>,
        datasets: [{
            data: <?= json_encode(array_column($pipeline, 'cnt')) ?>,
            backgroundColor: ['#2979FF','#FF6D00','#00E676','#AA00FF','#00BCD4','#FF1744'],
            borderWidth: 0
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        layout: { padding: { top: 30, bottom: 10, left: 30, right: 30 } },
        animation: { duration: 800, easing: 'easeOutQuart' },
        plugins: {
            legend: { position: 'bottom', labels: { color: '#fff', padding: 14, font: { size: 12 }, usePointStyle: false } },
            tooltip: { callbacks: { label: function(ctx) { var pct = pipeTotal>0 ? (ctx.raw/pipeTotal*100).toFixed(1) : 0; return ctx.label+': '+ctx.raw+'건 ('+pct+'%)'; } } }
        }
    },
    plugins: [{
        afterDraw: function(chart) {
            var ctx = chart.ctx;
            ctx.save();
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            chart.data.datasets[0].data.forEach(function(val, i) {
                if (val <= 0) return;
                var meta = chart.getDatasetMeta(0);
                var arc = meta.data[i];
                var props = arc.getProps(['x','y','startAngle','endAngle','innerRadius','outerRadius']);
                var midAngle = (props.startAngle + props.endAngle) / 2;
                var pct = pipeTotal > 0 ? (val/pipeTotal*100).toFixed(0) : 0;
                var label = chart.data.labels[i] || '';
                var angleDeg = (props.endAngle - props.startAngle) * 180 / Math.PI;
                if (angleDeg < 40) {
                    // 작은 영역: 바깥에 리더선 + 라벨
                    var innerPt = props.outerRadius + 5;
                    var outerPt = props.outerRadius + 25;
                    var x1 = props.x + Math.cos(midAngle) * innerPt;
                    var y1 = props.y + Math.sin(midAngle) * innerPt;
                    var x2 = props.x + Math.cos(midAngle) * outerPt;
                    var y2 = props.y + Math.sin(midAngle) * outerPt;
                    ctx.strokeStyle = 'rgba(255,255,255,0.4)';
                    ctx.lineWidth = 1;
                    ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.stroke();
                    ctx.font = '600 11px sans-serif';
                    ctx.fillStyle = '#fff';
                    ctx.fillText(label+' '+pct+'%', x2, y2 - 8);
                } else {
                    // 큰 영역: 안에 표시
                    var midRadius = (props.innerRadius + props.outerRadius) / 2;
                    var x = props.x + Math.cos(midAngle) * midRadius;
                    var y = props.y + Math.sin(midAngle) * midRadius;
                    ctx.font = '600 12px sans-serif';
                    ctx.fillStyle = '#fff';
                    ctx.fillText(label, x, y - 7);
                    ctx.fillText(pct+'%', x, y + 7);
                }
            });
            ctx.restore();
        }
    }]
});

// ── 3. 팀별 매출 수평 바 ──

// 직급별 파이프라인 도넛
<?php if (!$fGrade): ?>
var pipeGradeTotal = <?= $pipeGradeTotal ?>;
var pipeGradeChart = new Chart(document.getElementById('pipelineGradeChart'), {
    type: 'doughnut',
    data: {
        labels: <?= json_encode(array_column($pipelineGrade, 'grade')) ?>,
        datasets: [{
            data: <?= json_encode(array_column($pipelineGrade, 'cnt')) ?>,
            backgroundColor: ['#2979FF','#FF6D00','#00E676','#AA00FF','#00BCD4','#FF1744','#FFD600','#76FF03'],
            borderWidth: 0
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        animation: { duration: 800, easing: 'easeOutQuart' },
        plugins: {
            legend: { position: 'bottom', labels: { color: '#fff', padding: 14, font: { size: 12 }, usePointStyle: false } },
            tooltip: { callbacks: { label: function(ctx) { var pct = pipeGradeTotal>0 ? (ctx.raw/pipeGradeTotal*100).toFixed(1) : 0; return ctx.label+': '+ctx.raw+'건 ('+pct+'%)'; } } }
        }
    },
    plugins: [{
        afterDraw: function(chart) {
            var ctx = chart.ctx;
            ctx.save();
            ctx.font = '600 11px sans-serif';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            chart.data.datasets[0].data.forEach(function(val, i) {
                if (val <= 0) return;
                var meta = chart.getDatasetMeta(0);
                var arc = meta.data[i];
                var props = arc.getProps(['x','y','startAngle','endAngle','innerRadius','outerRadius']);
                var midAngle = (props.startAngle + props.endAngle) / 2;
                var midRadius = (props.innerRadius + props.outerRadius) / 2;
                var x = props.x + Math.cos(midAngle) * midRadius;
                var y = props.y + Math.sin(midAngle) * midRadius;
                var pct = pipeGradeTotal > 0 ? (val/pipeGradeTotal*100).toFixed(0) : 0;
                ctx.fillStyle = '#fff';
                ctx.fillText(pct+'%', x, y);
            });
            ctx.restore();
        }
    }]
});
<?php endif; ?>

function showPipeTab(tab) {
    var stageWrap = document.getElementById('pipeStageWrap');
    var gradeWrap = document.getElementById('pipeGradeWrap');
    var btnStage = document.getElementById('pipeTabStage');
    var btnGrade = document.getElementById('pipeTabGrade');
    if (tab === 'grade') {
        stageWrap.style.opacity = '0'; stageWrap.style.pointerEvents = 'none';
        setTimeout(function(){
            gradeWrap.style.opacity = '1'; gradeWrap.style.pointerEvents = 'auto';
            pipeGradeChart.reset(); pipeGradeChart.update();
        }, 350);
        btnStage.style.background = 'transparent'; btnStage.style.color = 'rgba(255,255,255,0.5)';
        btnGrade.style.background = 'var(--accent)'; btnGrade.style.color = 'var(--bg-color)';
    } else {
        gradeWrap.style.opacity = '0'; gradeWrap.style.pointerEvents = 'none';
        setTimeout(function(){
            stageWrap.style.opacity = '1'; stageWrap.style.pointerEvents = 'auto';
            pipeStageChart.reset(); pipeStageChart.update();
        }, 350);
        btnStage.style.background = 'var(--accent)'; btnStage.style.color = 'var(--bg-color)';
        btnGrade.style.background = 'transparent'; btnGrade.style.color = 'rgba(255,255,255,0.5)';
    }
}

// ── 3-orig. 팀별 매출 수평 바 ──
new Chart(document.getElementById('teamChart'), {
    type: 'bar',
    data: {
        labels: <?= json_encode(array_column($teamData, 'team')) ?>,
        datasets: [
            {
                label: '매출',
                data: <?= json_encode(array_map(fn($t)=>(int)$t['rev'], $teamData)) ?>,
                backgroundColor: 'rgba(41,121,255,0.7)',
                borderColor: '#2979FF',
                borderWidth: 1,
                borderRadius: 6
            },
            {
                label: '순이익',
                data: <?= json_encode(array_map(fn($t)=>(int)$t['profit'], $teamData)) ?>,
                backgroundColor: 'rgba(0,230,118,0.6)',
                borderColor: '#00E676',
                borderWidth: 1,
                borderRadius: 6
            }
        ]
    },
    options: {
        indexAxis: 'y',
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { position: 'top', labels: { color: 'rgba(255,255,255,0.6)', padding: 16 } } },
        scales: {
            x: { ticks: { callback: v => (v/10000).toLocaleString('ko-KR') + '만', color: 'rgba(255,255,255,0.4)', maxTicksLimit: 6 }, grid: { color: 'rgba(255,255,255,0.04)' }, beginAtZero: true },
            y: { ticks: { color: 'rgba(255,255,255,0.6)' }, grid: { color: 'rgba(255,255,255,0.04)' } }
        }
    }
});

// ── 4. 승인 현황 바 ──
new Chart(document.getElementById('approvalChart'), {
    type: 'bar',
    data: {
        labels: ['대기', '보류', '승인'],
        datasets: [{
            data: [<?= $approval['pending']??0 ?>, <?= $approval['hold']??0 ?>, <?= $approval['approved']??0 ?>],
            backgroundColor: ['rgba(255,255,255,0.15)','rgba(255,179,0,0.35)','rgba(76,175,80,0.35)'],
            borderColor: ['rgba(255,255,255,0.25)','rgba(255,179,0,0.6)','rgba(76,175,80,0.6)'],
            borderWidth: 1,
            borderRadius: 6
        }]
    },
    options: {
        indexAxis: 'y',
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: false } },
        scales: {
            x: { beginAtZero: true, ticks: { stepSize: 1, color: 'rgba(255,255,255,0.4)' }, grid: { color: 'rgba(255,255,255,0.04)' } },
            y: { ticks: { color: 'rgba(255,255,255,0.6)' }, grid: { display: false } }
        }
    }
});

function clearRelated(src) {
    // 월 선택 시 주/일 초기화
    if (src === 'month') {
        document.querySelector('[name=week]').value = '';
        document.querySelector('[name=day]').value = '';
    }
}
</script>

<style>
.badge-danger { background: #FFEBEE; color: #C62828; }
.dash-filter-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: nowrap;
    overflow-x: auto;
}
.dash-filter-label {
    font-size: 0.875rem;
    font-weight: 600;
    color: rgba(255,255,255,0.45);
    white-space: nowrap;
    flex-shrink: 0;
}
.dash-filter {
    height: 2.125rem;
    padding: 0 0.375rem;
    font-size: 0.875rem !important;
    font-weight: 600 !important;
    border: none;
    border-bottom: 1px solid var(--form-line-color, rgba(255,255,255,0.12));
    border-radius: 0;
    background: transparent;
    color: var(--text-primary, #fff);
    width: auto !important;
    min-width: 7rem;
    box-sizing: border-box;
    outline: none;
    font-family: inherit;
    flex-shrink: 0;
    transition: border-color 0.25s ease;
}
.dash-filter:hover {
    border-bottom-color: var(--accent, #E53935);
}
.dash-filter:focus {
    border-bottom-color: var(--accent, #E53935);
    box-shadow: 0 1px 0 var(--accent, #E53935);
}
.dash-filter-btn {
    height: 2.125rem;
    padding: 0 1rem;
    font-size: 0.875rem;
    line-height: 2.125rem;
    flex-shrink: 0;
}
</style>

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