import 'dart:convert'; import 'dart:developer'; import 'package:http/http.dart' as http; import 'package:sudoku_app/models/sudoku_game_dto.dart'; import 'package:sudoku_app/models/unified_rank_dto.dart'; import 'package:sudoku_app/models/game_rank_dto.dart'; class PuzzleService { final String _baseUrl = "https://lunaticbum.kr"; // ๐Ÿ‘ˆ HTTPS ํ™•์ธ // ๐Ÿ”ฝ [์ˆ˜์ •] 'blockSize' ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ Future startGame(String level, String blockSize) async { final response = await http.get( Uri.parse('$_baseUrl/puzzle/sudoku/start?level=$level&blockSizeStr=$blockSize'), ); if (response.statusCode == 200) { final data = jsonDecode(utf8.decode(response.bodyBytes)); return SudokuGameDto.fromJson(data); } else { throw Exception('๊ฒŒ์ž„ ๋กœ๋”ฉ ์‹คํŒจ: ${response.statusCode}'); } } // ๐Ÿ”ฝ [์ˆ˜์ •] puzzleId ๋Œ€์‹  question, answer, blockSize๋ฅผ ์ „์†ก Future validateSolution(String question, String answer, int blockSize) async { final response = await http.post( Uri.parse('$_baseUrl/puzzle/sudoku/validate'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({ 'question': question, // ๐Ÿ‘ˆ [์ˆ˜์ •] 'answer': answer, 'blockSize': blockSize, // ๐Ÿ‘ˆ [์ˆ˜์ •] }), ); if (response.statusCode == 200) { return jsonDecode(response.body)['correct'] ?? false; } else { log("์ •๋‹ต ํ™•์ธ ์‹คํŒจ: ${response.statusCode}"); log("์‘๋‹ต ๋ณธ๋ฌธ: ${response.body}"); throw Exception('์ •๋‹ต ํ™•์ธ ์‹คํŒจ: ${response.statusCode}'); } } // POST /api/ranks/submit Future submitRank(UnifiedRankDto rankDto) async { final response = await http.post( Uri.parse('$_baseUrl/api/ranks/submit'), headers: {'Content-Type': 'application/json'}, body: jsonEncode(rankDto.toJson()), ); if (response.statusCode != 200) { try { final errorBody = utf8.decode(response.bodyBytes); throw Exception(errorBody); } catch (e) { throw Exception('๋žญํ‚น ๋“ฑ๋ก ์‹คํŒจ: ${response.reasonPhrase}'); } } } Future> fetchRanks(String gameType, String? contextId) async { final queryParams = { 'gameType': gameType, if (contextId != null) 'contextId': contextId, }; // ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํฌํ•จํ•˜์—ฌ URI ์ƒ์„ฑ final uri = Uri.parse('$_baseUrl/api/ranks/list').replace(queryParameters: queryParams); final response = await http.get(uri); if (response.statusCode == 200) { // ์„œ๋ฒ„์—์„œ [ ... ] ํ˜•ํƒœ์˜ JSON ๋ฐฐ์—ด์„ ๋ฐ›์Œ final List data = jsonDecode(utf8.decode(response.bodyBytes)); // ๊ฐ JSON ๊ฐ์ฒด๋ฅผ GameRankDto๋กœ ๋ณ€ํ™˜ return data.map((json) => GameRankDto.fromJson(json)).toList(); } else { throw Exception('๋žญํ‚น ๋กœ๋”ฉ ์‹คํŒจ'); } } }