import 'dart:convert';
import 'dart:developer';
import 'package:http/http.dart' as http;
import 'package:service_api/models/sudoku_game_dto.dart';
import 'package:service_api/models/unified_rank_dto.dart';
import 'package:service_api/models/game_rank_dto.dart';

class PuzzleService {
  final String _baseUrl = "https://lunaticbum.kr"; 

  // 🔽 [수정] 'difficulty' 파라미터 1개만 받음 (1~11)
  Future<SudokuGameDto> startGame(String difficulty) async {
    final response = await http.get(
      // 🔽 [수정] 'difficulty' 파라미터만 전달
      Uri.parse('$_baseUrl/puzzle/sudoku/start?difficulty=$difficulty'),
    );

    if (response.statusCode == 200) {
      final data = jsonDecode(utf8.decode(response.bodyBytes));
      return SudokuGameDto.fromJson(data);
    } else {
      throw Exception('게임 로딩 실패: ${response.statusCode}');
    }
  }

  // 'puzzleId'를 받아 검증 (서버 DTO와 일치)
  Future<bool> validateSolution(int puzzleId, String answer) async {
    final response = await http.post(
      Uri.parse('$_baseUrl/puzzle/sudoku/validate'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'puzzleId': puzzleId,
        'answer': answer,
      }),
    );

    if (response.statusCode == 200) {
      return jsonDecode(response.body)['correct'] ?? false;
    } else {
      log("정답 확인 실패: ${response.statusCode}");
      log("응답 본문: ${response.body}"); 
      throw Exception('정답 확인 실패: ${response.statusCode}');
    }
  }

  // 🔽 [전체 수정] submitRank 함수
  // 반환 타입이 Future<RankSubmissionResult>로 변경되었습니다.
  Future<RankSubmissionResult> submitRank(UnifiedRankDto rankDto) async {
    
    final requestBody = jsonEncode(rankDto.toJson());
    log(">>> 랭킹 등록 요청: $requestBody");

    final response = await http.post(
      // 🔽 [수정] API 경로가 /api/ranks/submit
      Uri.parse('$_baseUrl/api/ranks/submit'),
      headers: {'Content-Type': 'application/json'},
      body: requestBody,
    );

    // 🔽 [수정] 성공(200) 시, 서버가 반환한 RankSubmissionResult 객체를 파싱
    if (response.statusCode == 200) {
      log("<<< 랭킹 등록 성공: 200 OK (RankSubmissionResult 반환됨)");
      try {
        final Map<String, dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
        // 🔽 [수정] RankSubmissionResult.fromJson으로 파싱
        return RankSubmissionResult.fromJson(data);
      } catch (e) {
        log("<<< 랭킹 등록 성공했으나, 반환된 랭킹 목록 파싱 실패: $e");
        throw Exception('랭킹 목록 파싱 실패: $e');
      }
    } 
    // 🔽 [수정] 실패 시, 기존 로직과 동일하게 에러 처리
    else {
      log("<<< 랭킹 등록 실패: ${response.statusCode}");
      try {
        final errorBody = utf8.decode(response.bodyBytes);
        log("<<< 서버 에러 메시지: $errorBody");
        throw Exception(errorBody);
      } catch (e) {
         throw Exception('랭킹 등록 실패: ${response.reasonPhrase}');
      }
    }
  }

  // 랭킹 조회
  Future<List<GameRankDto>> fetchRanks(String gameType, String? contextId) async {
    final queryParams = {
      'gameType': gameType,
      if (contextId != null) 'contextId': contextId,
    };
    final uri = Uri.parse('$_baseUrl/api/ranks/list').replace(queryParameters: queryParams);
    
    final response = await http.get(uri);

    if (response.statusCode == 200) {
      final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
      return data.map((json) => GameRankDto.fromJson(json)).toList();
    } else {
      // [🔥 수정] 실패 시 HTTP 상태 코드 명시
      log("랭킹 로딩 실패: HTTP Status ${response.statusCode}");
      throw Exception('랭킹 로딩 실패: HTTP Status ${response.statusCode}');
    }
  }
}