<?php
require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/includes/db.php';
require_once dirname(__DIR__) . '/includes/functions.php';
require_once dirname(__DIR__) . '/includes/auth.php';
require_once dirname(__DIR__) . '/includes/layout.php';
require_once dirname(__DIR__) . '/includes/playback_failures.php';

requirePermission('playback_failure_manage');
ensurePlaybackFailureTables();

$pdo = getDBConnection();
$typeLabels = playbackFailureTypeLabels();
$statusLabels = playbackFailureStatusLabels();
$errors = [];
$success = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    requireCsrfToken();
    $action = (string)($_POST['action'] ?? '');
    if ($action === 'update_status') {
        $id = (int)($_POST['id'] ?? 0);
        $status = (string)($_POST['status'] ?? 'new');
        $adminNote = trim(maskInternalPathText(ensureUtf8String($_POST['admin_note'] ?? '')));
        if (function_exists('mb_substr')) {
            $adminNote = mb_substr($adminNote, 0, 1000, 'UTF-8');
        } else {
            $adminNote = substr($adminNote, 0, 1000);
        }

        if ($id <= 0) {
            $errors[] = '대상을 찾을 수 없습니다.';
        } elseif (!array_key_exists($status, $statusLabels)) {
            $errors[] = '처리 상태가 올바르지 않습니다.';
        } else {
            try {
                $handledAt = in_array($status, ['resolved', 'ignored'], true) ? date('Y-m-d H:i:s') : null;
                $stmt = $pdo->prepare("
                    UPDATE app_playback_failures
                    SET status = :status,
                        admin_note = :admin_note,
                        handled_by_admin = :handled_by_admin,
                        handled_at = :handled_at,
                        updated_at = NOW()
                    WHERE id = :id
                ");
                $stmt->execute([
                    ':status' => $status,
                    ':admin_note' => $adminNote !== '' ? $adminNote : null,
                    ':handled_by_admin' => (int)($_SESSION['admin_user_id'] ?? 0),
                    ':handled_at' => $handledAt,
                    ':id' => $id,
                ]);
                writeAuditLog('playback_failure_status_update', 'Playback failure #' . $id . ' status updated to ' . $status, 'success', 'info', 'playback_failure', $id);
                header('Location: playback_failures.php?id=' . $id . '&updated=1');
                exit;
            } catch (Throwable $e) {
                $errors[] = '처리 상태 저장 중 문제가 발생했습니다.';
                if (function_exists('writeAppLog')) {
                    writeAppLog('error', 'playback_failure_error', 'Playback failure status update failed', [
                        'failure_id' => $id,
                        'error' => limitLogText($e->getMessage(), 300),
                    ]);
                }
            }
        }
    }
}

if (isset($_GET['updated'])) {
    $success = '처리 상태를 저장했습니다.';
}

$selectedType = (string)($_GET['type'] ?? '');
$selectedStatus = (string)($_GET['status'] ?? '');
$period = (string)($_GET['period'] ?? '30');
$query = trim((string)($_GET['q'] ?? ''));
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = 24;
$offset = ($page - 1) * $limit;

$where = [];
$params = [];
if ($selectedType !== '' && array_key_exists($selectedType, $typeLabels)) {
    $where[] = 'f.error_type = :error_type';
    $params[':error_type'] = $selectedType;
}
if ($selectedStatus !== '' && array_key_exists($selectedStatus, $statusLabels)) {
    $where[] = 'f.status = :status';
    $params[':status'] = $selectedStatus;
}
if (in_array($period, ['7', '30', '90'], true)) {
    $where[] = 'f.last_seen_at >= DATE_SUB(NOW(), INTERVAL ' . (int)$period . ' DAY)';
}
if ($query !== '') {
    $where[] = '(s.title LIKE :q_title OR s.artist LIKE :q_artist OR CAST(f.song_id AS CHAR) = :q_id)';
    $like = '%' . $query . '%';
    $params[':q_title'] = $like;
    $params[':q_artist'] = $like;
    $params[':q_id'] = $query;
}
$whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';

$countStmt = $pdo->prepare("SELECT COUNT(*) FROM app_playback_failures f LEFT JOIN songs s ON s.id = f.song_id $whereSql");
$countStmt->execute($params);
$total = (int)$countStmt->fetchColumn();
$totalPages = max(1, (int)ceil($total / $limit));

$listSql = "
    SELECT f.id, f.song_id, f.error_type, f.status, f.failure_count, f.last_seen_at, f.last_http_status,
           f.last_client_code, f.last_source, s.title AS song_title, s.artist AS song_artist
    FROM app_playback_failures f
    LEFT JOIN songs s ON s.id = f.song_id
    $whereSql
    ORDER BY f.last_seen_at DESC, f.id DESC
    LIMIT $limit OFFSET $offset
";
$listStmt = $pdo->prepare($listSql);
$listStmt->execute($params);
$rows = $listStmt->fetchAll();

$selectedId = (int)($_GET['id'] ?? 0);
$selectedFailure = null;
$events = [];
if ($selectedId > 0) {
    $detailStmt = $pdo->prepare("
        SELECT f.*, s.title AS song_title, s.artist AS song_artist, s.album AS song_album
        FROM app_playback_failures f
        LEFT JOIN songs s ON s.id = f.song_id
        WHERE f.id = :id
    ");
    $detailStmt->execute([':id' => $selectedId]);
    $selectedFailure = $detailStmt->fetch() ?: null;
    if ($selectedFailure) {
        $eventStmt = $pdo->prepare("
            SELECT id, error_type, http_status, client_code, source, user_id, context, created_at
            FROM app_playback_failure_events
            WHERE failure_id = :failure_id
            ORDER BY created_at DESC, id DESC
            LIMIT 20
        ");
        $eventStmt->execute([':failure_id' => $selectedId]);
        $events = $eventStmt->fetchAll();
    }
}

function playbackFailureBuildQuery($overrides = []) {
    $params = array_merge($_GET, $overrides);
    foreach ($params as $key => $value) {
        if ($value === '' || $value === null) unset($params[$key]);
    }
    return 'playback_failures.php' . ($params ? '?' . http_build_query($params) : '');
}

renderHeader('재생 실패 관리', 'playback_failures');
?>
<div class="admin-dashboard feedback-admin-page playback-failure-page">
    <div class="page-title-section">
        <h1 class="page-main-title">재생 실패 관리</h1>
        <p class="page-subtitle">파일 없음, Range 오류, 브라우저 재생 오류처럼 실제 재생 중 발생한 문제 곡을 확인합니다.</p>
    </div>

    <?php if ($success !== ''): ?><div class="alert success"><?php echo h($success); ?></div><?php endif; ?>
    <?php foreach ($errors as $error): ?><div class="alert error"><?php echo h($error); ?></div><?php endforeach; ?>

    <section class="home-section feedback-admin-filter">
        <form method="get" class="feedback-filter-form">
            <select name="status" aria-label="처리 상태">
                <option value="">모든 상태</option>
                <?php foreach ($statusLabels as $value => $label): ?>
                    <option value="<?php echo h($value); ?>" <?php echo $selectedStatus === $value ? 'selected' : ''; ?>><?php echo h($label); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="type" aria-label="오류 유형">
                <option value="">모든 오류 유형</option>
                <?php foreach ($typeLabels as $value => $label): ?>
                    <option value="<?php echo h($value); ?>" <?php echo $selectedType === $value ? 'selected' : ''; ?>><?php echo h($label); ?></option>
                <?php endforeach; ?>
            </select>
            <select name="period" aria-label="기간">
                <option value="7" <?php echo $period === '7' ? 'selected' : ''; ?>>최근 7일</option>
                <option value="30" <?php echo $period === '30' ? 'selected' : ''; ?>>최근 30일</option>
                <option value="90" <?php echo $period === '90' ? 'selected' : ''; ?>>최근 90일</option>
                <option value="all" <?php echo $period === 'all' ? 'selected' : ''; ?>>전체</option>
            </select>
            <input type="search" name="q" value="<?php echo h($query); ?>" placeholder="곡명, 아티스트, 곡 ID">
            <button class="btn btn-primary" type="submit"><i class="fa-solid fa-magnifying-glass"></i> 검색</button>
            <a class="btn btn-secondary" href="playback_failures.php">초기화</a>
        </form>
        <p class="settings-muted">총 <?php echo number_format($total); ?>건</p>
    </section>

    <div class="feedback-admin-layout">
        <section class="home-section feedback-admin-list">
            <div class="section-heading-row">
                <h2 class="section-title">실패 목록</h2>
                <span class="pill"><?php echo number_format($page); ?> / <?php echo number_format($totalPages); ?>페이지</span>
            </div>
            <?php if (empty($rows)): ?>
                <p class="empty-text">조건에 맞는 재생 실패 기록이 없습니다.</p>
            <?php else: ?>
                <div class="feedback-ticket-list">
                    <?php foreach ($rows as $row): ?>
                        <a class="feedback-ticket <?php echo $selectedId === (int)$row['id'] ? 'active' : ''; ?>" href="<?php echo h(playbackFailureBuildQuery(['id' => (int)$row['id']])); ?>">
                            <span class="feedback-ticket-meta">
                                <b class="feedback-type-badge type-<?php echo h($row['error_type']); ?>"><?php echo h(playbackFailureTypeLabel($row['error_type'])); ?></b>
                                <b class="feedback-status-badge status-<?php echo h($row['status']); ?>"><?php echo h(playbackFailureStatusLabel($row['status'])); ?></b>
                                <b class="feedback-status-badge"><?php echo number_format((int)$row['failure_count']); ?>회</b>
                            </span>
                            <strong><?php echo h($row['song_title'] ?: ('곡 #' . (int)$row['song_id'])); ?></strong>
                            <small><?php echo h($row['song_artist'] ?: '-'); ?> · 마지막 <?php echo h($row['last_seen_at']); ?></small>
                        </a>
                    <?php endforeach; ?>
                </div>
                <?php if ($totalPages > 1): ?>
                    <div class="pagination">
                        <?php if ($page > 1): ?><a class="btn btn-secondary btn-sm" href="<?php echo h(playbackFailureBuildQuery(['page' => $page - 1])); ?>">이전</a><?php endif; ?>
                        <?php if ($page < $totalPages): ?><a class="btn btn-secondary btn-sm" href="<?php echo h(playbackFailureBuildQuery(['page' => $page + 1])); ?>">다음</a><?php endif; ?>
                    </div>
                <?php endif; ?>
            <?php endif; ?>
        </section>

        <section class="home-section feedback-admin-detail">
            <?php if (!$selectedFailure): ?>
                <p class="empty-text">왼쪽 목록에서 실패 기록을 선택하면 상세 내용을 확인할 수 있습니다.</p>
            <?php else: ?>
                <div class="feedback-detail-head">
                    <div>
                        <span class="feedback-ticket-meta">
                            <b class="feedback-type-badge type-<?php echo h($selectedFailure['error_type']); ?>"><?php echo h(playbackFailureTypeLabel($selectedFailure['error_type'])); ?></b>
                            <b class="feedback-status-badge status-<?php echo h($selectedFailure['status']); ?>"><?php echo h(playbackFailureStatusLabel($selectedFailure['status'])); ?></b>
                        </span>
                        <h2><?php echo h($selectedFailure['song_title'] ?: ('곡 #' . (int)$selectedFailure['song_id'])); ?></h2>
                    </div>
                    <small>#<?php echo (int)$selectedFailure['id']; ?></small>
                </div>
                <dl class="feedback-detail-meta">
                    <div><dt>곡 ID</dt><dd><?php echo (int)$selectedFailure['song_id']; ?></dd></div>
                    <div><dt>아티스트</dt><dd><?php echo h($selectedFailure['song_artist'] ?: '-'); ?></dd></div>
                    <div><dt>앨범</dt><dd><?php echo h($selectedFailure['song_album'] ?: '-'); ?></dd></div>
                    <div><dt>발생 횟수</dt><dd><?php echo number_format((int)$selectedFailure['failure_count']); ?>회</dd></div>
                    <div><dt>최초/마지막</dt><dd><?php echo h($selectedFailure['first_seen_at']); ?> / <?php echo h($selectedFailure['last_seen_at']); ?></dd></div>
                    <div><dt>최근 상태</dt><dd>HTTP <?php echo h($selectedFailure['last_http_status'] ?: '-'); ?> · <?php echo h($selectedFailure['last_client_code'] ?: '-'); ?> · <?php echo h($selectedFailure['last_source'] ?: '-'); ?></dd></div>
                </dl>
                <div class="feedback-body-box">
                    <strong>최근 실패 이력</strong>
                    <?php if (empty($events)): ?>
                        <p class="empty-text">별도 이벤트 이력이 없습니다. 짧은 시간 반복 실패는 집계만 증가합니다.</p>
                    <?php else: ?>
                        <div class="admin-log-list">
                            <?php foreach ($events as $event): ?>
                                <div class="admin-log-row compact">
                                    <strong><?php echo h(playbackFailureTypeLabel($event['error_type'])); ?> · <?php echo h($event['source'] ?: '-'); ?></strong>
                                    <span><?php echo h($event['created_at']); ?></span>
                                    <p>HTTP <?php echo h($event['http_status'] ?: '-'); ?> · <?php echo h($event['client_code'] ?: '-'); ?> · <?php echo h($event['context'] ?: '-'); ?></p>
                                </div>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>
                <form method="post" class="feedback-status-form">
                    <?php echo csrfInput(); ?>
                    <input type="hidden" name="action" value="update_status">
                    <input type="hidden" name="id" value="<?php echo (int)$selectedFailure['id']; ?>">
                    <label>
                        처리 상태
                        <select name="status">
                            <?php foreach ($statusLabels as $value => $label): ?>
                                <option value="<?php echo h($value); ?>" <?php echo $selectedFailure['status'] === $value ? 'selected' : ''; ?>><?php echo h($label); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </label>
                    <label>
                        조치 메모
                        <textarea name="admin_note" rows="4" maxlength="1000" placeholder="파일 재스캔, 원본 확인, 무시 사유 등을 남겨주세요."><?php echo h($selectedFailure['admin_note'] ?? ''); ?></textarea>
                    </label>
                    <button class="btn btn-primary" type="submit"><i class="fa-solid fa-floppy-disk"></i> 상태 저장</button>
                </form>
            <?php endif; ?>
        </section>
    </div>
</div>
<?php renderFooter(); ?>
