import 'package:get_it/get_it.dart';
import 'package:superport/models/user_model.dart';
import 'package:superport/core/controllers/base_list_controller.dart';
import 'package:superport/data/models/common/pagination_params.dart';
import 'package:superport/domain/usecases/user/get_users_usecase.dart';
import 'package:superport/domain/usecases/user/create_user_usecase.dart';
import 'package:superport/domain/usecases/user/check_username_availability_usecase.dart';
import 'package:superport/domain/repositories/user_repository.dart';
import 'package:superport/domain/repositories/company_repository.dart';
import 'package:superport/models/company_item_model.dart';
import 'package:superport/core/errors/failures.dart';

/// 사용자 목록 화면 컨트롤러 (서버 API v0.2.1 대응)
/// Clean Architecture Presentation Layer - 새로운 UseCase 패턴 적용
class UserListController extends BaseListController<User> {
  late final GetUsersUseCase _getUsersUseCase;
  late final CreateUserUseCase _createUserUseCase;
  late final CheckUsernameAvailabilityUseCase _checkUsernameUseCase;
  late final UserRepository _userRepository;
  late final CompanyRepository _companyRepository;
  
  // 필터 옵션 (서버 API v0.2.1 지원 필드만)
  UserRole? _filterRole;
  bool? _filterIsActive;
  bool _includeInactive = false;
  
  // Getters
  List<User> get users => items;
  UserRole? get filterRole => _filterRole;
  bool? get filterIsActive => _filterIsActive;
  bool get includeInactive => _includeInactive;
  
  // 사용자명 중복 체크 상태
  bool _usernameCheckInProgress = false;
  bool get isCheckingUsername => _usernameCheckInProgress;
  
  // 회사 선택 관련 상태
  List<CompanyItem> _companies = [];
  int? _selectedCompanyId;
  bool _isLoadingCompanies = false;
  
  List<CompanyItem> get companies => _companies;
  int? get selectedCompanyId => _selectedCompanyId;
  bool get isLoadingCompanies => _isLoadingCompanies;

  UserListController() {
    _getUsersUseCase = GetIt.instance<GetUsersUseCase>();
    _createUserUseCase = GetIt.instance<CreateUserUseCase>();
    _checkUsernameUseCase = GetIt.instance<CheckUsernameAvailabilityUseCase>();
    _userRepository = GetIt.instance<UserRepository>();
    _companyRepository = GetIt.instance<CompanyRepository>();
    
    // 초기화 시 회사 목록 로드
    loadCompanies();
  }

  @override
  Future<PagedResult<User>> fetchData({
    required PaginationParams params,
    Map<String, dynamic>? additionalFilters,
  }) async {
    final getUsersParams = GetUsersParams(
      page: params.page,
      perPage: params.perPage,
      role: _filterRole,
      isActive: _filterIsActive,
    );
    
    final result = await _getUsersUseCase(getUsersParams);
    
    return result.fold(
      (failure) => throw _mapFailureToException(failure),
      (paginatedResponse) {
        final meta = PaginationMeta(
          currentPage: paginatedResponse.page,
          perPage: paginatedResponse.size,
          total: paginatedResponse.totalElements,
          totalPages: paginatedResponse.totalPages,
          hasNext: !paginatedResponse.last,
          hasPrevious: !paginatedResponse.first,
        );
        
        return PagedResult(items: paginatedResponse.items, meta: meta);
      },
    );
  }

  @override
  bool filterItem(User item, String query) {
    final q = query.toLowerCase();
    return item.name.toLowerCase().contains(q) ||
           (item.email?.toLowerCase().contains(q) ?? false) ||
           item.username.toLowerCase().contains(q);
  }

  /// 필터 설정 (서버 API v0.2.1 지원 필드만)
  void setFilters({
    UserRole? role,
    bool? isActive,
    String? roleString,
  }) {
    // String으로 들어온 role을 UserRole로 변환
    if (roleString != null) {
      try {
        _filterRole = UserRole.fromString(roleString);
      } catch (e) {
        _filterRole = null;
      }
    } else {
      _filterRole = role;
    }
    _filterIsActive = isActive;
    loadData(isRefresh: true);
  }

  /// 필터 초기화
  void clearFilters() {
    _filterRole = null;
    _filterIsActive = null;
    search('');
    loadData(isRefresh: true);
  }

  /// 역할별 필터링 (새 권한 시스템)
  void filterByRole(UserRole? role) {
    _filterRole = role;
    loadData(isRefresh: true);
  }

  /// 활성 상태별 필터링
  void filterByActiveStatus(bool? isActive) {
    _filterIsActive = isActive;
    loadData(isRefresh: true);
  }

  /// 회사 목록 로드
  Future<void> loadCompanies() async {
    _isLoadingCompanies = true;
    notifyListeners();
    
    try {
      final result = await _companyRepository.getCompanies();
      result.fold(
        (failure) {
          // 에러 처리는 로그만 남기고 계속 진행
          print('회사 목록 로드 실패: ${failure.message}');
        },
        (paginatedResponse) {
          _companies = paginatedResponse.items
              .map((company) => CompanyItem.headquarters(company))
              .toList();
          // 첫 번째 회사를 기본 선택
          if (_companies.isNotEmpty && _selectedCompanyId == null) {
            _selectedCompanyId = _companies.first.company.id;
          }
        },
      );
    } catch (e) {
      print('회사 목록 로드 중 예외 발생: $e');
    } finally {
      _isLoadingCompanies = false;
      notifyListeners();
    }
  }
  
  /// 회사 선택
  void selectCompany(int? companyId) {
    _selectedCompanyId = companyId;
    notifyListeners();
  }

  /// 사용자 생성
  Future<void> createUser({
    required String username,
    required String email,
    required String password,
    required String name,
    String? phone,
    required UserRole role,
    int? companiesId,
  }) async {
    final effectiveCompanyId = companiesId ?? _selectedCompanyId;
    
    if (effectiveCompanyId == null) {
      throw Exception('회사를 선택해주세요.');
    }
    
    final params = CreateUserParams(
      name: name,
      email: email,
      phone: phone,
      companiesId: effectiveCompanyId,
    );
    
    final result = await _createUserUseCase(params);
    
    result.fold(
      (failure) {
        throw _mapFailureToException(failure);
      },
      (user) {
        // 성공 시 목록 새로고침
        refresh();
      },
    );
  }

  /// 사용자 수정
  Future<void> updateUser(User user, {String? newPassword}) async {
    final result = await _userRepository.updateUser(
      user.id!,
      user,
      newPassword: newPassword,
    );
    
    result.fold(
      (failure) {
        throw _mapFailureToException(failure);
      },
      (updatedUser) {
        updateItemLocally(updatedUser, (u) => u.id == updatedUser.id);
      },
    );
  }

  /// 사용자 삭제 (소프트 딜리트)
  Future<void> deleteUser(int id) async {
    final result = await _userRepository.deleteUser(id);
    
    result.fold(
      (failure) {
        throw _mapFailureToException(failure);
      },
      (_) {
        removeItemLocally((u) => u.id == id);
      },
    );
  }

  /// 사용자명 중복 확인
  Future<bool> checkUsernameAvailability(String username) async {
    _usernameCheckInProgress = true;
    notifyListeners();
    
    try {
      final params = CheckUsernameAvailabilityParams(username: username);
      final result = await _checkUsernameUseCase(params);
      
      return result.fold(
        (failure) {
          throw _mapFailureToException(failure);
        },
        (isAvailable) => isAvailable,
      );
    } finally {
      _usernameCheckInProgress = false;
      notifyListeners();
    }
  }

  /// 사용자 역할 한글명 반환
  String getRoleDisplayName(UserRole role) {
    return role.displayName;
  }

  /// 사용자 ID로 단일 사용자 조회
  User? getUserById(int id) {
    try {
      return items.firstWhere((user) => user.id == id);
    } catch (e) {
      return null;
    }
  }

  /// UI 호환성을 위한 메서드들
  
  /// 검색어 설정 (UI 호환용)
  void setSearchQuery(String query) {
    search(query);
  }
  
  /// 데이터 로드 (UI 호환용)
  void loadUsers({bool refresh = false}) {
    if (refresh) {
      this.refresh();
    } else {
      loadData();
    }
  }
  
  /// 사용자 상태 변경
  Future<void> changeUserStatus(User user, bool newStatus) async {
    final updatedUser = user.copyWith(isActive: newStatus);
    await updateUser(updatedUser);
  }
  
  /// 비활성 사용자 포함 토글
  void toggleIncludeInactive() {
    _includeInactive = !_includeInactive;
    _filterIsActive = _includeInactive ? null : true;
    loadData(isRefresh: true);
  }

  /// Failure를 Exception으로 매핑하는 헬퍼 메서드
  Exception _mapFailureToException(Failure failure) {
    if (failure is ValidationFailure) {
      return Exception('입력값 검증 실패: ${failure.message}');
    } else if (failure is NotFoundFailure) {
      return Exception('사용자를 찾을 수 없습니다: ${failure.message}');
    } else if (failure is DuplicateFailure) {
      return Exception('중복된 데이터가 있습니다: ${failure.message}');
    } else if (failure is AuthenticationFailure) {
      return Exception('인증이 필요합니다: ${failure.message}');
    } else if (failure is AuthorizationFailure) {
      return Exception('권한이 없습니다: ${failure.message}');
    } else {
      return Exception('오류가 발생했습니다: ${failure.message}');
    }
  }
}