import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/data/models/administrator_dto.dart';
import 'package:superport/domain/usecases/administrator_usecase.dart';
import 'package:superport/core/constants/app_constants.dart';

/// 관리자 화면 컨트롤러 (Provider 패턴)
/// 관리자 목록 조회, CRUD, 검색 등의 상태 관리
@injectable
class AdministratorController extends ChangeNotifier {
  final AdministratorUseCase _administratorUseCase;
  
  AdministratorController(this._administratorUseCase);

  // 상태 변수들
  List<AdministratorDto> _administrators = [];
  AdministratorDto? _selectedAdministrator;
  bool _isLoading = false;
  String? _errorMessage;
  
  // 페이지네이션
  int _currentPage = 1;
  int _totalPages = 1;
  int _totalCount = 0;
  final int _pageSize = AppConstants.adminPageSize;
  
  // 검색
  String _searchQuery = '';
  
  // Form 관련 상태
  bool _isFormSubmitting = false;
  String? _formErrorMessage;
  
  // Getters
  List<AdministratorDto> get administrators => _administrators;
  AdministratorDto? get selectedAdministrator => _selectedAdministrator;
  bool get isLoading => _isLoading;
  String? get errorMessage => _errorMessage;
  int get currentPage => _currentPage;
  int get totalPages => _totalPages;
  int get totalCount => _totalCount;
  int get pageSize => _pageSize;
  String get searchQuery => _searchQuery;
  bool get hasNextPage => _currentPage < _totalPages;
  bool get hasPreviousPage => _currentPage > 1;
  
  // Form 관련 Getters
  bool get isFormSubmitting => _isFormSubmitting;
  String? get formErrorMessage => _formErrorMessage;

  /// 컨트롤러 초기화
  Future<void> initialize() async {
    _isLoading = true;
    notifyListeners();
    
    await loadAdministrators();
  }

  /// 관리자 목록 로드
  Future<void> loadAdministrators({bool refresh = false}) async {
    if (refresh) {
      _currentPage = 1;
    }

    _setLoading(true);
    _clearError();

    try {
      final result = await _administratorUseCase.getAdministrators(
        page: _currentPage,
        pageSize: _pageSize,
        search: _searchQuery.isNotEmpty ? _searchQuery : null,
      );

      result.fold(
        (failure) {
          _setError('관리자 목록을 불러오는데 실패했습니다: ${failure.message}');
        },
        (response) {
          _administrators = List.from(response.items);
          _totalCount = response.totalCount;
          _totalPages = response.totalPages;
          _currentPage = response.currentPage;
          notifyListeners();
        },
      );
    } catch (e) {
      _setError('관리자 목록을 불러오는데 실패했습니다: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 특정 관리자 선택/조회
  Future<void> selectAdministrator(int id) async {
    _setLoading(true);
    _clearError();

    try {
      final result = await _administratorUseCase.getAdministratorById(id);

      result.fold(
        (failure) {
          _setError('관리자 정보를 불러오는데 실패했습니다: ${failure.message}');
        },
        (administrator) {
          _selectedAdministrator = administrator;
          notifyListeners();
        },
      );
    } catch (e) {
      _setError('관리자 정보를 불러오는데 실패했습니다: ${e.toString()}');
    } finally {
      _setLoading(false);
    }
  }

  /// 관리자 생성
  Future<bool> createAdministrator({
    required String name,
    required String phone,
    required String mobile,
    required String email,
    required String password,
  }) async {
    _setFormSubmitting(true);
    _clearFormError();

    try {
      final request = AdministratorRequestDto(
        name: name.trim(),
        phone: phone.trim(),
        mobile: mobile.trim(),
        email: email.trim(),
        passwd: password,
      );

      final result = await _administratorUseCase.createAdministrator(request);

      return result.fold(
        (failure) {
          _setFormError('관리자 생성에 실패했습니다: ${failure.message}');
          return false;
        },
        (administrator) {
          // 목록 새로고침
          loadAdministrators(refresh: true);
          return true;
        },
      );
    } catch (e) {
      _setFormError('관리자 생성에 실패했습니다: ${e.toString()}');
      return false;
    } finally {
      _setFormSubmitting(false);
    }
  }

  /// 관리자 정보 수정
  Future<bool> updateAdministrator(
    int id, {
    String? name,
    String? phone,
    String? mobile,
    String? email,
    String? password,
  }) async {
    _setFormSubmitting(true);
    _clearFormError();

    try {
      final request = AdministratorUpdateRequestDto(
        name: name?.trim(),
        phone: phone?.trim(),
        mobile: mobile?.trim(),
        email: email?.trim(),
        passwd: password,
      );

      final result = await _administratorUseCase.updateAdministrator(id, request);

      return result.fold(
        (failure) {
          _setFormError('관리자 정보 수정에 실패했습니다: ${failure.message}');
          return false;
        },
        (administrator) {
          // 목록 새로고침
          loadAdministrators(refresh: true);
          // 선택된 관리자 업데이트
          if (_selectedAdministrator?.id == id) {
            _selectedAdministrator = administrator;
          }
          notifyListeners();
          return true;
        },
      );
    } catch (e) {
      _setFormError('관리자 정보 수정에 실패했습니다: ${e.toString()}');
      return false;
    } finally {
      _setFormSubmitting(false);
    }
  }

  /// 관리자 삭제
  Future<bool> deleteAdministrator(int id) async {
    _setLoading(true);
    _clearError();

    try {
      final result = await _administratorUseCase.deleteAdministrator(id);

      return result.fold(
        (failure) {
          _setError('관리자 삭제에 실패했습니다: ${failure.message}');
          return false;
        },
        (_) {
          // 목록에서 제거
          _administrators.removeWhere((admin) => admin.id == id);
          // 선택된 관리자가 삭제된 경우 클리어
          if (_selectedAdministrator?.id == id) {
            _selectedAdministrator = null;
          }
          // 총 개수 업데이트
          _totalCount--;
          notifyListeners();
          return true;
        },
      );
    } catch (e) {
      _setError('관리자 삭제에 실패했습니다: ${e.toString()}');
      return false;
    } finally {
      _setLoading(false);
    }
  }

  /// 검색 쿼리 설정
  void setSearchQuery(String query) {
    _searchQuery = query.trim();
    loadAdministrators(refresh: true);
  }

  /// 검색 초기화
  void clearSearch() {
    if (_searchQuery.isNotEmpty) {
      _searchQuery = '';
      loadAdministrators(refresh: true);
    }
  }

  /// 다음 페이지 로드
  Future<void> loadNextPage() async {
    if (hasNextPage && !_isLoading) {
      _currentPage++;
      await loadAdministrators();
    }
  }

  /// 이전 페이지 로드
  Future<void> loadPreviousPage() async {
    if (hasPreviousPage && !_isLoading) {
      _currentPage--;
      await loadAdministrators();
    }
  }

  /// 특정 페이지로 이동
  Future<void> goToPage(int page) async {
    if (page > 0 && page <= _totalPages && page != _currentPage && !_isLoading) {
      _currentPage = page;
      await loadAdministrators();
    }
  }

  /// 이메일 중복 확인
  Future<bool> checkEmailDuplicate(String email, {int? excludeId}) async {
    try {
      final result = await _administratorUseCase.checkEmailDuplicate(
        email.trim(),
        excludeId: excludeId,
      );

      return result.fold(
        (failure) => true, // 에러 시 안전하게 중복으로 처리
        (isDuplicate) => isDuplicate,
      );
    } catch (e) {
      return true; // 에러 시 안전하게 중복으로 처리
    }
  }

  /// 선택된 관리자 클리어
  void clearSelectedAdministrator() {
    _selectedAdministrator = null;
    notifyListeners();
  }

  /// 목록 새로고침
  Future<void> refresh() async {
    await loadAdministrators(refresh: true);
  }

  // 내부 상태 관리 메서드들
  void _setLoading(bool loading) {
    _isLoading = loading;
    notifyListeners();
  }

  void _setError(String error) {
    _errorMessage = error;
    notifyListeners();
  }

  void _clearError() {
    _errorMessage = null;
  }

  void _setFormSubmitting(bool submitting) {
    _isFormSubmitting = submitting;
    notifyListeners();
  }

  void _setFormError(String error) {
    _formErrorMessage = error;
    notifyListeners();
  }

  void _clearFormError() {
    _formErrorMessage = null;
  }

  @override
  void dispose() {
    // 추가적인 정리 작업이 필요한 경우 여기서 수행
    super.dispose();
  }
}