import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../config/api_config.dart';
import '../models/score_model.dart';
import './api_service.dart';

class ScoreService with ChangeNotifier {
  List<Score> _scores = [];
  bool _isLoading = false;
  String? _token;
  String? _clubId;
  ApiService _apiService = ApiService();
  String? _memberId;
  String? _eventId;
  DateTime? _lastLoadedAt;
  String? _lastError;
  
  // 테스트용 생성자
  ScoreService.forTest(ApiService apiService, {String? clubId, String? memberId, String? eventId}) {
    _apiService = apiService;
    if (clubId != null) {
      _clubId = clubId;
    }
    if (memberId != null) {
      _memberId = memberId;
    }
    if (eventId != null) {
      _eventId = eventId;
    }
  }
  
  // 테스트용 getter
  String? get testMemberId => _memberId;
  String? get testEventId => _eventId;
  
  // 기본 생성자
  ScoreService();

  List<Score> get scores => [..._scores];
  bool get isLoading => _isLoading;
  DateTime? get lastLoadedAt => _lastLoadedAt;
  String? get lastError => _lastError;

  // 초기화 함수
  void initialize(String token) {
    _token = token;
    _apiService.setToken(token);
  }

  // 회원 ID 설정
  void setMemberId(String memberId) {
    _memberId = memberId;
    notifyListeners();
  }

  // 이벤트 ID 설정
  void setEventId(String eventId) {
    _eventId = eventId;
    notifyListeners();
  }

  // 클럽의 모든 점수 가져오기
  Future<void> fetchClubScores() async {
    print('fetchClubScores 호출됨: token=$_token');

    _isLoading = true;
    _lastError = null;
    notifyListeners();

    try {
      // 클럽 ID 가져오기
      final prefs = await SharedPreferences.getInstance();
      final clubId = prefs.getString(ApiConfig.clubIdKey);

      if (clubId == null) {
        throw Exception('선택된 클럽이 없습니다');
      }

      final data = await _apiService.post(
        '${ApiConfig.clubs}/scores',
        data: {'clubId': clubId},
      );

      // 응답 데이터가 리스트 형태로 직접 왔는지 확인
      if (data is List) {
        final List<dynamic> scoresData = data;
        _scores = scoresData
            .map((scoreData) => Score.fromJson(scoreData))
            .toList();
      } else {
        // 응답 데이터가 객체 형태로 왔을 경우 scores 키를 통해 접근
        final List<dynamic> scoresData = data['scores'] ?? [];
        _scores = scoresData
            .map((scoreData) => Score.fromJson(scoreData))
            .toList();
      }

      _isLoading = false;
      _lastLoadedAt = DateTime.now();
      notifyListeners();
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('점수 목록을 불러오는데 실패했습니다: $e');
    }
  }

  // 회원의 점수 가져오기
  Future<List<Score>> fetchMemberScores(String memberId) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 또는 클럽 정보가 필요합니다');
    }

    _isLoading = true;
    _lastError = null;
    notifyListeners();

    try {
      final data = await _apiService.post(
        '${ApiConfig.clubs}/members/scores',
        data: {'memberId': memberId},
      );

      final List<dynamic> scoresData = data['scores'];

      final memberScores = scoresData
          .map((scoreData) => Score.fromJson(scoreData))
          .toList();

      _isLoading = false;
      notifyListeners();

      return memberScores;
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('회원 점수를 불러오는데 실패했습니다: $e');
    }
  }

  // 이벤트의 점수 가져오기
  Future<List<Score>> fetchEventScores(String eventId) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 또는 클럽 정보가 필요합니다');
    }

    _isLoading = true;
    _lastError = null;
    notifyListeners();

    try {
      final data = await _apiService.post(
        '${ApiConfig.clubs}/events/scores',
        data: {'eventId': eventId},
      );

      final List<dynamic> scoresData = data['scores'];

      final eventScores = scoresData
          .map((scoreData) => Score.fromJson(scoreData))
          .toList();

      _isLoading = false;
      notifyListeners();

      return eventScores;
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('이벤트 점수를 불러오는데 실패했습니다: $e');
    }
  }

  // 점수 추가
  Future<Score> addScore(Map<String, dynamic> scoreData) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 또는 클럽 정보가 필요합니다');
    }

    _isLoading = true;
    _lastError = null;
    notifyListeners();

    try {
      final data = await _apiService.post(ApiConfig.scores, data: scoreData);

      final newScore = Score.fromJson(data['score']);

      _scores.add(newScore);

      _isLoading = false;
      notifyListeners();

      return newScore;
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('점수 추가에 실패했습니다: $e');
    }
  }

  // 점수 수정
  Future<Score> updateScore(
    String scoreId,
    Map<String, dynamic> updates,
  ) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 또는 클럽 정보가 필요합니다');
    }

    _isLoading = true;
    notifyListeners();

    try {
      final data = await _apiService.put(
        '${ApiConfig.scores}/$scoreId',
        data: updates,
      );

      final updatedScore = Score.fromJson(data['score']);

      // 점수 목록 업데이트
      final index = _scores.indexWhere((score) => score.id == scoreId);
      if (index >= 0) {
        _scores[index] = updatedScore;
      }

      _isLoading = false;
      notifyListeners();

      return updatedScore;
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('점수 수정에 실패했습니다: $e');
    }
  }

  // 점수 삭제
  Future<bool> deleteScore(String scoreId) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 또는 클럽 정보가 필요합니다');
    }

    _isLoading = true;
    notifyListeners();

    try {
      await _apiService.delete('${ApiConfig.scores}/$scoreId');

      // 점수 목록에서 삭제
      _scores.removeWhere((score) => score.id == scoreId);

      _isLoading = false;
      notifyListeners();

      return true;
    } catch (e) {
      _isLoading = false;
      _lastError = e.toString();
      notifyListeners();
      throw Exception('점수 삭제에 실패했습니다: $e');
    }
  }

  // 회원 통계 가져오기
  Future<ScoreStatistics> fetchMemberStatistics(String memberId) async {
    if (_token == null || _clubId == null) {
      throw Exception('인증 정보가 필요합니다');
    }

    _lastError = null;

    try {
      final data = await _apiService.post(
        '${ApiConfig.clubs}/members/stats',
        data: {'memberId': memberId},
      );

      _lastLoadedAt = DateTime.now();
      return ScoreStatistics.fromJson(data['statistics']);
    } catch (e) {
      _lastError = e.toString();
      throw Exception('회원 통계를 불러오는데 실패했습니다: $e');
    }
  }

  // 클럽 통계 가져오기
  Future<Map<String, ScoreStatistics>> fetchClubStatistics() async {
    if (_token == null) {
      throw Exception('인증 정보가 필요합니다');
    }

    try {
      // 클럽 ID 가져오기
      final prefs = await SharedPreferences.getInstance();
      final clubId = prefs.getString(ApiConfig.clubIdKey);

      if (clubId == null) {
        throw Exception('선택된 클럽이 없습니다');
      }

      final data = await _apiService.post(
        '${ApiConfig.clubs}/scores/stats',
        data: {'clubId': clubId},
      );

      final Map<String, ScoreStatistics> statistics = {};

      if (data['statistics'] != null) {
        final Map<String, dynamic> statsData =
            data['statistics'] as Map<String, dynamic>;

        statsData.forEach((key, value) {
          if (value != null) {
            try {
              statistics[key] = ScoreStatistics.fromJson(value);
            } catch (e) {
              print('통계 변환 오류: $key - $e');
            }
          }
        });
      }

      _lastLoadedAt = DateTime.now();
      _lastError = null;
      return statistics;
    } catch (e) {
      _lastError = e.toString();
      throw Exception('클럽 통계를 불러오는데 실패했습니다: $e');
    }
  }
}
