<?php
// 출력 버퍼링 시작
while (ob_get_level()) {
    ob_end_clean();
}
ob_start();

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

require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");

// 에러 응답 함수
function sendErrorResponse($message, $details = null) {
    while (ob_get_level()) {
        ob_end_clean();
    }
    header('Content-Type: application/json; charset=utf-8');
    $response = ['ok' => false, 'error' => $message];
    if ($details !== null) {
        $response['details'] = $details;
    }
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
    exit;
}

// 출력 버퍼 비우기
ob_clean();
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');

// 1. 권한 체크
if (!isset($user_id) || $level > 5) {
    sendErrorResponse('접근 권한이 없습니다.');
}

// 2. 파라미터 확인
$meeting_id = isset($_GET['meeting_id']) ? (int)$_GET['meeting_id'] : 0;
$operation_name = isset($_GET['operation_name']) ? trim($_GET['operation_name']) : '';

if (!$meeting_id || !$operation_name) {
    sendErrorResponse('필수 파라미터가 없습니다.', 'meeting_id와 operation_name이 필요합니다.');
}

// 3. Google API 인증 정보 가져오기
$googleServiceAccountFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/google_service_account.json';
$googleApiKeyFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/google_api.txt';

$accessToken = null;
$googleApiKey = null;

// 서비스 계정 우선 사용
if (file_exists($googleServiceAccountFile)) {
    $serviceAccount = json_decode(file_get_contents($googleServiceAccountFile), true);
    if ($serviceAccount) {
        // OAuth 2.0 토큰 생성
        $now = time();
        $jwtHeader = ['alg' => 'RS256', 'typ' => 'JWT'];
        $jwtClaim = [
            'iss' => $serviceAccount['client_email'],
            'scope' => 'https://www.googleapis.com/auth/cloud-platform',
            'aud' => 'https://oauth2.googleapis.com/token',
            'exp' => $now + 3600,
            'iat' => $now
        ];
        
        $base64UrlEncode = function($data) {
            return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
        };
        
        $encodedHeader = $base64UrlEncode(json_encode($jwtHeader));
        $encodedClaim = $base64UrlEncode(json_encode($jwtClaim));
        
        $privateKey = openssl_pkey_get_private($serviceAccount['private_key']);
        if ($privateKey) {
            $signature = '';
            $signData = $encodedHeader . '.' . $encodedClaim;
            if (openssl_sign($signData, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
                openssl_free_key($privateKey);
                $encodedSignature = $base64UrlEncode($signature);
                $jwt = $encodedHeader . '.' . $encodedClaim . '.' . $encodedSignature;
                
                // OAuth 토큰 요청
                $tokenCh = curl_init('https://oauth2.googleapis.com/token');
                curl_setopt($tokenCh, CURLOPT_POST, true);
                curl_setopt($tokenCh, CURLOPT_POSTFIELDS, http_build_query([
                    'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                    'assertion' => $jwt
                ]));
                curl_setopt($tokenCh, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($tokenCh, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
                
                $tokenResponse = curl_exec($tokenCh);
                $tokenCode = curl_getinfo($tokenCh, CURLINFO_HTTP_CODE);
                curl_close($tokenCh);
                
                if ($tokenCode === 200) {
                    $tokenData = json_decode($tokenResponse, true);
                    if (isset($tokenData['access_token'])) {
                        $accessToken = $tokenData['access_token'];
                    }
                }
            }
        }
    }
}

// API 키 사용
if (!$accessToken && file_exists($googleApiKeyFile)) {
    $googleApiKey = trim(file_get_contents($googleApiKeyFile));
}

if (!$accessToken && !$googleApiKey) {
    sendErrorResponse('Google API 인증 정보가 없습니다.');
}

// 4. Google API에서 작업 상태 확인
if ($accessToken) {
    $poll_url = 'https://speech.googleapis.com/v1/operations/' . urlencode($operation_name);
    $poll_headers = ['Authorization: Bearer ' . $accessToken];
} else {
    $poll_url = 'https://speech.googleapis.com/v1/operations/' . urlencode($operation_name) . '?key=' . urlencode($googleApiKey);
    $poll_headers = [];
}

$poll_ch = curl_init($poll_url);
curl_setopt($poll_ch, CURLOPT_RETURNTRANSFER, true);
if (!empty($poll_headers)) {
    curl_setopt($poll_ch, CURLOPT_HTTPHEADER, $poll_headers);
}
curl_setopt($poll_ch, CURLOPT_TIMEOUT, 30);

$poll_response = curl_exec($poll_ch);
$poll_code = curl_getinfo($poll_ch, CURLINFO_HTTP_CODE);
$poll_error = curl_error($poll_ch);
curl_close($poll_ch);

if ($poll_code !== 200) {
    sendErrorResponse('작업 상태 확인 실패 (HTTP ' . $poll_code . ')', $poll_error ?: substr($poll_response, 0, 500));
}

$poll_data = json_decode($poll_response, true);
if (!$poll_data) {
    sendErrorResponse('작업 상태 응답 파싱 실패', substr($poll_response, 0, 500));
}

// 5. 작업 완료 여부 확인
if (!isset($poll_data['done']) || $poll_data['done'] !== true) {
    // 아직 처리 중
    echo json_encode([
        'ok' => true,
        'processing' => true,
        'done' => false,
        'message' => '음성 인식 처리 중입니다. 잠시 후 다시 확인해주세요.'
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

// 6. 작업 완료 - 결과 처리
if (isset($poll_data['error'])) {
    // 오류 발생
    $pdo = db_connect();
    $errorMsg = isset($poll_data['error']['message']) ? $poll_data['error']['message'] : '알 수 없는 오류';
    
    $updateSql = "UPDATE meeting_logs SET 
                  title = ?, 
                  summary_text = ? 
                  WHERE id = ?";
    $updateStmt = $pdo->prepare($updateSql);
    $updateStmt->execute(['오류 발생', 'Google STT 변환 실패: ' . $errorMsg, $meeting_id]);
    
    echo json_encode([
        'ok' => false,
        'error' => 'Google STT 변환 실패',
        'details' => $errorMsg
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

// 응답 구조 확인 및 로깅
error_log('Google STT 응답 구조: ' . json_encode([
    'has_response' => isset($poll_data['response']),
    'has_results' => isset($poll_data['response']['results']),
    'results_count' => isset($poll_data['response']['results']) ? count($poll_data['response']['results']) : 0,
    'response_keys' => isset($poll_data['response']) ? array_keys($poll_data['response']) : [],
    'poll_data_keys' => array_keys($poll_data)
], JSON_UNESCAPED_UNICODE));

// response 필드가 없는 경우
if (!isset($poll_data['response'])) {
    error_log('Google STT 응답에 response 필드가 없습니다. 전체 응답: ' . json_encode($poll_data, JSON_UNESCAPED_UNICODE));
    sendErrorResponse('Google STT 응답 구조 오류', '응답에 response 필드가 없습니다. 작업이 완료되었지만 결과를 가져올 수 없습니다.');
}

// results가 없는 경우
if (!isset($poll_data['response']['results'])) {
    error_log('Google STT 응답에 results 필드가 없습니다. response 내용: ' . json_encode($poll_data['response'], JSON_UNESCAPED_UNICODE));
    sendErrorResponse('Google STT 응답에 결과가 없습니다.', '응답에 results 필드가 없습니다. 음성이 인식되지 않았을 수 있습니다.');
}

// results가 비어있는 경우
if (empty($poll_data['response']['results'])) {
    error_log('Google STT 응답에 results가 비어있습니다. response 내용: ' . json_encode($poll_data['response'], JSON_UNESCAPED_UNICODE));
    
    // 빈 결과를 DB에 저장하고 사용자에게 알림
    $pdo = db_connect();
    $updateSql = "UPDATE meeting_logs SET 
                  title = ?, 
                  transcript_text = ?, 
                  summary_text = ? 
                  WHERE id = ?";
    $updateStmt = $pdo->prepare($updateSql);
    $updateStmt->execute(['음성 인식 실패', '음성이 인식되지 않았습니다.', '녹음된 오디오에서 음성을 인식할 수 없었습니다. 마이크 권한과 오디오 품질을 확인해주세요.', $meeting_id]);
    
    sendErrorResponse('음성 인식 실패', '녹음된 오디오에서 음성을 인식할 수 없었습니다. 마이크 권한과 오디오 품질을 확인해주세요.');
}

// 7. 텍스트 변환
$stt_data = ['results' => $poll_data['response']['results']];
$transcript = '';
foreach ($stt_data['results'] as $result) {
    if (isset($result['alternatives'][0]['transcript'])) {
        $transcript .= $result['alternatives'][0]['transcript'] . ' ';
    }
}
$transcript = trim($transcript);

if (empty($transcript)) {
    sendErrorResponse('인식된 텍스트가 없습니다.');
}

// 8. Claude API로 요약 생성
$claudeKeyFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/claude_api.txt';
$claudeKey = '';
if (file_exists($claudeKeyFile)) {
    $claudeKey = trim(file_get_contents($claudeKeyFile));
}

$title = '무제 회의록';
$summary = '';

if (!empty($claudeKey)) {
    $prompt = "다음 회의 녹취록을 분석하여 JSON 형식으로 응답해주세요.

요구사항:
1. \"title\": 회의 내용을 요약한 제목 (최대 20자, 한글 기준)
2. \"summary\": [회의 개요 / 주요 안건 / 결정 사항 / 향후 계획] 형식의 상세 요약

반드시 다음 JSON 형식으로만 응답해주세요:
{
  \"title\": \"제목 (최대 20자)\",
  \"summary\": \"상세 요약 내용\"
}

회의 녹취록:
" . $transcript;

    $ch2 = curl_init('https://api.anthropic.com/v1/messages');
    $requestBody = [
        'model' => 'claude-3-5-haiku-20241022',
        'max_tokens' => 2048,
        'messages' => [['role' => 'user', 'content' => $prompt]]
    ];

    curl_setopt($ch2, CURLOPT_POST, true);
    curl_setopt($ch2, CURLOPT_HTTPHEADER, [
        'x-api-key: ' . $claudeKey,
        'anthropic-version: 2023-06-01',
        'Content-Type: application/json'
    ]);
    curl_setopt($ch2, CURLOPT_POSTFIELDS, json_encode($requestBody));
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

    $ai_response = curl_exec($ch2);
    $ai_code = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
    curl_close($ch2);

    if ($ai_code === 200) {
        $ai_data = json_decode($ai_response, true);
        if (isset($ai_data['content'][0]['text'])) {
            $ai_text = trim($ai_data['content'][0]['text']);
            $ai_text = preg_replace('/^```(?:json)?\s*/m', '', $ai_text);
            $ai_text = preg_replace('/\s*```$/m', '', $ai_text);
            $ai_text = trim($ai_text);
            
            $parsed_data = json_decode($ai_text, true);
            
            if (is_array($parsed_data)) {
                if (isset($parsed_data['title']) && !empty($parsed_data['title'])) {
                    $title = mb_substr(trim($parsed_data['title']), 0, 20, 'UTF-8');
                }
                if (isset($parsed_data['summary']) && !empty($parsed_data['summary'])) {
                    $summary = $parsed_data['summary'];
                } else {
                    $summary = $ai_text;
                }
            } else {
                $summary = $ai_text;
                if (preg_match('/["\']?title["\']?\s*[:=]\s*["\']([^"\']{1,20})["\']/', $ai_text, $matches)) {
                    $title = mb_substr(trim($matches[1]), 0, 20, 'UTF-8');
                } elseif (preg_match('/제목[:\s]+([^\n]{1,20})/', $ai_text, $matches)) {
                    $title = mb_substr(trim($matches[1]), 0, 20, 'UTF-8');
                } else {
                    $lines = explode("\n", $ai_text);
                    $first_line = trim($lines[0]);
                    if (!empty($first_line) && mb_strlen($first_line, 'UTF-8') <= 20) {
                        $title = $first_line;
                    } elseif (!empty($first_line)) {
                        $title = mb_substr($first_line, 0, 20, 'UTF-8');
                    }
                }
            }
        }
    }
}

if (empty($title) || $title === '무제 회의록') {
    if (!empty($summary)) {
        $summary_lines = explode("\n", $summary);
        $first_summary_line = trim($summary_lines[0]);
        if (!empty($first_summary_line)) {
            $first_summary_line = preg_replace('/[\[\(].*?[\]\)]/', '', $first_summary_line);
            $first_summary_line = trim($first_summary_line);
            if (mb_strlen($first_summary_line, 'UTF-8') <= 20) {
                $title = $first_summary_line;
            } else {
                $title = mb_substr($first_summary_line, 0, 20, 'UTF-8');
            }
        }
    }
}

$title = mb_substr(trim($title), 0, 20, 'UTF-8');
if (empty($title)) {
    $title = '무제 회의록';
}

if (empty($summary)) {
    $summary = "Claude API 키가 설정되지 않아 요약을 생성할 수 없습니다. (원문 저장됨)";
}

// 9. DB 업데이트
$pdo = db_connect();
$updateSql = "UPDATE meeting_logs SET 
              title = ?, 
              transcript_text = ?, 
              summary_text = ? 
              WHERE id = ?";
$updateStmt = $pdo->prepare($updateSql);
$updateStmt->execute([$title, $transcript, $summary, $meeting_id]);

// 10. 완료 응답
@ob_clean();
@ob_end_clean();
header('Content-Type: application/json; charset=utf-8');

echo json_encode([
    'ok' => true,
    'processing' => false,
    'done' => true,
    'meeting_id' => $meeting_id,
    'title' => $title,
    'transcript' => $transcript,
    'summary' => $summary,
    'message' => '음성 인식 및 요약이 완료되었습니다.'
], JSON_UNESCAPED_UNICODE);
?>

