<?php

namespace App\Controllers\Manage;

use App\Controllers\BaseController;

class WorkerLog extends BaseController
{
    /**
     * Worker 로그 통합 뷰어
     */
    public function index()
    {
        $this->data['title'] = 'Worker 로그 통합 관리';
        
        // 로그 디렉토리 목록
        $logDirs = [
            'api_receiver' => ROOTPATH . 'worker/logs',
            'naver_worker' => WRITEPATH . 'logs/worker'
        ];
        
        // 날짜 필터 (기본값: 오늘)
        $date = $this->request->getGet('date') ?? date('Y-m-d');
        $logType = $this->request->getGet('type') ?? 'all';
        
        $logs = [];
        
        // API Receiver 로그 읽기
        if ($logType === 'all' || $logType === 'api_receiver') {
            $apiLogFile = $logDirs['api_receiver'] . '/' . $date . '.log';
            if (file_exists($apiLogFile)) {
                $logs['api_receiver'] = $this->parseLogFile($apiLogFile);
            }
        }
        
        // Naver Worker 로그 읽기
        if ($logType === 'all' || $logType === 'naver_worker') {
            $workerLogFile = $logDirs['naver_worker'] . '/' . $date . '.log';
            if (file_exists($workerLogFile)) {
                $logs['naver_worker'] = $this->parseLogFile($workerLogFile);
            }
            
            // Failed 로그도 읽기
            $failedLogFile = $logDirs['naver_worker'] . '/' . $date . '_failed.log';
            if (file_exists($failedLogFile)) {
                $logs['naver_worker_failed'] = $this->parseLogFile($failedLogFile);
            }
        }
        
        // 모든 로그를 시간순으로 통합 정렬
        $allLogs = [];
        foreach ($logs as $type => $entries) {
            foreach ($entries as $entry) {
                $entry['source'] = $type;
                $allLogs[] = $entry;
            }
        }
        
        // 시간 역순 정렬 (최신순)
        usort($allLogs, function($a, $b) {
            return strtotime($b['timestamp']) - strtotime($a['timestamp']);
        });
        
        $this->data['logs'] = $allLogs;
        $this->data['date'] = $date;
        $this->data['logType'] = $logType;
        $this->data['logDirs'] = $logDirs;
        
        // 사용 가능한 날짜 목록 (최근 30일)
        $this->data['availableDates'] = $this->getAvailableLogDates($logDirs);
        
        return view('pages/manage/worker_log', $this->data);
    }
    
    /**
     * 로그 파일 파싱
     */
    private function parseLogFile($filePath)
    {
        $logs = [];
        $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        
        foreach ($lines as $line) {
            // 로그 포맷: [2025-12-22 10:30:45] [INFO] [NaverWorker::run:95] 메시지
            if (preg_match('/\[(.+?)\]\s*\[(.+?)\]\s*(?:\[(.+?)\]\s*)?(.+)/', $line, $matches)) {
                $logs[] = [
                    'timestamp' => $matches[1],
                    'level' => $matches[2],
                    'location' => $matches[3] ?? '',
                    'message' => $matches[4]
                ];
            } else {
                // 파싱 실패한 경우 원본 그대로
                $logs[] = [
                    'timestamp' => date('Y-m-d H:i:s'),
                    'level' => 'UNKNOWN',
                    'location' => '',
                    'message' => $line
                ];
            }
        }
        
        return $logs;
    }
    
    /**
     * 로그 파일이 존재하는 날짜 목록 가져오기
     */
    private function getAvailableLogDates($logDirs)
    {
        $dates = [];
        
        foreach ($logDirs as $dir) {
            if (!is_dir($dir)) continue;
            
            $files = scandir($dir);
            foreach ($files as $file) {
                if (preg_match('/(\d{4}-\d{2}-\d{2})(?:_failed)?\.log$/', $file, $matches)) {
                    $dates[$matches[1]] = true;
                }
            }
        }
        
        $dates = array_keys($dates);
        rsort($dates); // 최신순 정렬
        
        return array_slice($dates, 0, 30); // 최근 30일만
    }
    
    /**
     * 실시간 로그 스트리밍 (Ajax)
     */
    public function stream()
    {
        $type = $this->request->getGet('type') ?? 'naver_worker';
        $lastId = (int) ($this->request->getGet('lastId') ?? 0);
        
        $logDirs = [
            'api_receiver' => ROOTPATH . 'worker/logs',
            'naver_worker' => WRITEPATH . 'logs/worker'
        ];
        
        $logFile = $logDirs[$type] . '/' . date('Y-m-d') . '.log';
        
        $newLogs = [];
        if (file_exists($logFile)) {
            $lines = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            
            // lastId 이후의 로그만 반환
            if ($lastId < count($lines)) {
                $newLines = array_slice($lines, $lastId);
                
                foreach ($newLines as $line) {
                    if (preg_match('/\[(.+?)\]\s*\[(.+?)\]\s*(?:\[(.+?)\]\s*)?(.+)/', $line, $matches)) {
                        $newLogs[] = [
                            'timestamp' => $matches[1],
                            'level' => $matches[2],
                            'location' => $matches[3] ?? '',
                            'message' => $matches[4]
                        ];
                    }
                }
            }
        }
        
        return $this->response->setJSON([
            'success' => true,
            'logs' => $newLogs,
            'lastId' => $lastId + count($newLogs)
        ]);
    }
    
    /**
     * 로그 파일 다운로드
     */
    public function download()
    {
        $date = $this->request->getGet('date') ?? date('Y-m-d');
        $type = $this->request->getGet('type') ?? 'naver_worker';
        
        $logDirs = [
            'api_receiver' => ROOTPATH . 'worker/logs',
            'naver_worker' => WRITEPATH . 'logs/worker'
        ];
        
        $logFile = $logDirs[$type] . '/' . $date . '.log';
        
        if (!file_exists($logFile)) {
            return $this->response->setStatusCode(404)->setBody('로그 파일을 찾을 수 없습니다.');
        }
        
        return $this->response->download($logFile, null);
    }
    
    /**
     * 로그 파일 삭제
     */
    public function delete()
    {
        $date = $this->request->getPost('date');
        $type = $this->request->getPost('type');
        
        if (!$date || !$type) {
            return $this->response->setJSON(['success' => false, 'message' => '필수 파라미터 누락']);
        }
        
        $logDirs = [
            'api_receiver' => ROOTPATH . 'worker/logs',
            'naver_worker' => WRITEPATH . 'logs/worker'
        ];
        
        $logFile = $logDirs[$type] . '/' . $date . '.log';
        
        if (file_exists($logFile)) {
            unlink($logFile);
            return $this->response->setJSON(['success' => true, 'message' => '로그 파일이 삭제되었습니다.']);
        }
        
        return $this->response->setJSON(['success' => false, 'message' => '로그 파일을 찾을 수 없습니다.']);
    }
}
