import 'package:flutter/material.dart';
import '../constants/app_constants.dart';
import '../utils/error_handler.dart';
import '../../data/models/common/pagination_params.dart';

/// 모든 리스트 컨트롤러의 기본 클래스
/// 
/// 페이지네이션, 검색, 필터, 에러 처리 등 공통 기능을 제공합니다.
/// 개별 컨트롤러는 이 클래스를 상속받아 특화된 로직만 구현하면 됩니다.
abstract class BaseListController<T> extends ChangeNotifier {
  /// 전체 아이템 목록
  List<T> _items = [];
  
  /// 필터링된 아이템 목록
  List<T> _filteredItems = [];
  
  /// 로딩 상태
  bool _isLoading = false;
  
  /// 에러 메시지
  String? _error;
  
  /// 검색 쿼리
  String _searchQuery = '';
  
  /// 현재 페이지 번호
  int _currentPage = 1;
  
  /// 페이지당 아이템 수
  int _pageSize = AppConstants.defaultPageSize;
  
  /// 더 많은 데이터가 있는지 여부
  bool _hasMore = true;
  
  /// 전체 아이템 수 (서버에서 제공하는 실제 전체 개수)
  int _total = 0;
  
  /// 총 페이지 수
  int _totalPages = 0;
  
  /// Controller가 dispose되었는지 여부
  bool _isDisposed = false;
  
  BaseListController();
  
  /// 안전한 notifyListeners 호출 (dispose 후에는 호출하지 않음)
  @override
  void notifyListeners() {
    if (!_isDisposed) {
      super.notifyListeners();
    }
  }
  
  /// 컨트롤러 초기화 (페이지 크기 설정 및 데이터 로드)
  Future<void> initialize({int pageSize = AppConstants.defaultPageSize}) async {
    _pageSize = pageSize;
    await loadData(isRefresh: true);
  }
  
  // Getters
  List<T> get items => _filteredItems;
  bool get isLoading => _isLoading;
  String? get error => _error;
  String get searchQuery => _searchQuery;
  int get currentPage => _currentPage;
  int get pageSize => _pageSize;
  bool get hasMore => _hasMore;
  int get total => _total;
  int get totalCount => _total; // Alias for total
  int get totalPages => _totalPages;
  
  // Setters
  set pageSize(int value) {
    _pageSize = value;
    notifyListeners();
  }
  
  // Protected setters for subclasses
  @protected
  set isLoadingState(bool value) {
    _isLoading = value;
  }
  
  @protected
  set errorState(String? value) {
    _error = value;
  }
  
  /// 데이터 로드 (하위 클래스에서 구현)
  /// PagedResult를 반환하여 페이지네이션 메타데이터를 포함
  Future<PagedResult<T>> fetchData({
    required PaginationParams params,
    Map<String, dynamic>? additionalFilters,
  });
  
  /// 아이템 필터링 (하위 클래스에서 선택적으로 오버라이드)
  bool filterItem(T item, String query) {
    // 기본 구현: toString()을 사용한 간단한 필터링
    return item.toString().toLowerCase().contains(query.toLowerCase());
  }
  
  /// 데이터 로드 및 관리
  Future<void> loadData({
    bool isRefresh = false,
    Map<String, dynamic>? additionalFilters,
    int? targetPage, // 특정 페이지를 지정할 수 있도록 추가
  }) async {
    if (_isLoading) return;
    
    if (isRefresh) {
      _currentPage = targetPage ?? 1; // targetPage가 있으면 사용, 없으면 1
      // Freezed 객체의 unmodifiable list 문제 해결: clear() 대신 새 리스트 할당
      _items = [];
      _filteredItems = [];
      _hasMore = true;
    }
    
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      // PaginationParams 생성
      final params = PaginationParams(
        page: _currentPage,
        perPage: _pageSize,
        search: _searchQuery.isNotEmpty ? _searchQuery : null,
      );
      
      // 데이터 가져오기
      final result = await fetchData(
        params: params,
        additionalFilters: additionalFilters,
      );
      
      if (isRefresh) {
        // Freezed 객체의 unmodifiable list를 mutable list로 변환
        _items = List<T>.from(result.items);
      } else {
        // 기존 리스트에 추가할 때도 새 리스트 생성
        _items = List<T>.from(_items)..addAll(result.items);
      }
      
      // 메타데이터 업데이트 - 서버 응답의 페이지 번호로 동기화
      _total = result.meta.total;
      _totalPages = result.meta.totalPages;
      _hasMore = result.meta.hasNext;
      _currentPage = result.meta.currentPage; // 서버 응답의 페이지 번호로 동기화
      
      _applyFiltering();
    } catch (e) {
      if (e is AppFailure) {
        _error = ErrorHandler.getUserFriendlyMessage(e);
      } else {
        _error = '데이터를 불러오는 중 오류가 발생했습니다.';
      }
      print('[BaseListController] Error loading data: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  /// 다음 페이지 로드
  Future<void> loadNextPage() async {
    if (!_hasMore || _isLoading) return;
    _currentPage++; // 다음 페이지로 증가
    await loadData(isRefresh: false);
  }
  
  /// 검색 (서버 검색과 연동)
  void search(String query) {
    _searchQuery = query;
    loadData(isRefresh: true); // 서버 검색 수행
  }
  
  /// 특정 페이지로 이동
  void goToPage(int page) {
    if (page < 1 || page > _totalPages && _totalPages > 0) return;
    if (page == _currentPage) return;
    
    loadData(isRefresh: true, targetPage: page);
  }
  
  /// 필터링 적용
  void _applyFiltering() {
    if (_searchQuery.isEmpty) {
      _filteredItems = List<T>.from(_items);
    } else {
      _filteredItems = _items.where((item) => filterItem(item, _searchQuery)).toList();
    }
  }
  
  /// 새로고침
  Future<void> refresh() async {
    await loadData(isRefresh: true);
  }
  
  /// 에러 초기화
  void clearError() {
    _error = null;
    notifyListeners();
  }
  
  /// 아이템 추가 (로컬)
  void addItemLocally(T item) {
    _items.insert(0, item);
    _applyFiltering();
    _total++;
    notifyListeners();
  }
  
  /// 아이템 업데이트 (로컬)
  void updateItemLocally(T item, bool Function(T) matcher) {
    final index = _items.indexWhere(matcher);
    if (index != -1) {
      _items[index] = item;
      _applyFiltering();
      notifyListeners();
    }
  }
  
  /// 아이템 삭제 (로컬)
  void removeItemLocally(bool Function(T) matcher) {
    _items.removeWhere(matcher);
    _applyFiltering();
    _total--;
    notifyListeners();
  }
  
  /// 리소스 정리
  @override
  void dispose() {
    _isDisposed = true;
    super.dispose();
  }
}