import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/company_item_model.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/core/utils/error_handler.dart';
import 'package:superport/core/controllers/base_list_controller.dart';
import 'package:superport/data/models/common/pagination_params.dart';
import 'package:superport/domain/entities/company_hierarchy.dart';
import 'package:superport/domain/usecases/company/get_company_hierarchy_usecase.dart';
import 'package:superport/domain/usecases/company/update_parent_company_usecase.dart';
import 'package:superport/domain/usecases/company/validate_company_deletion_usecase.dart';

/// 회사 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러 (리팩토링 버전)
/// BaseListController를 상속받아 공통 기능을 재사용
/// CompanyItem 모델을 사용하여 회사와 지점을 통합 관리
class CompanyListController extends BaseListController<CompanyItem> {
  late final CompanyService _companyService;
  late final GetCompanyHierarchyUseCase _getCompanyHierarchyUseCase;
  late final UpdateParentCompanyUseCase _updateParentCompanyUseCase;
  late final ValidateCompanyDeletionUseCase _validateCompanyDeletionUseCase;
  
  // 추가 상태 관리
  final Set<int> selectedCompanyIds = {};
  int _actualHeadquartersCount = 0; // 실제 본사 개수 (헤드쿼터 API 기준)
  
  // 계층 구조 관련
  CompanyHierarchy? _companyHierarchy;
  bool _isTreeView = false;
  final Map<String, bool> _expandedNodes = {};
  
  // 필터
  bool? _isActiveFilter;
  CompanyType? _typeFilter;
  bool _includeInactive = false; // 비활성 회사 포함 여부
  
  // Getters
  List<CompanyItem> get companyItems => items;
  List<CompanyItem> get filteredCompanyItems => items;
  
  /// 실제 본사 개수 (헤드쿼터 API 기준) - 화면 표시용
  int get actualHeadquartersCount => _actualHeadquartersCount;
  
  /// 현재 화면에 표시된 본사 개수 (필터링 후)
  int get displayedHeadquartersCount => items.where((item) => !item.isBranch).length;
  
  // 호환성을 위한 기존 getter (deprecated, 사용하지 말 것)
  @deprecated
  List<Company> get companies => items.where((item) => !item.isBranch).map((item) => item.company).toList();
  @deprecated
  List<Company> get filteredCompanies => companies;
  bool? get isActiveFilter => _isActiveFilter;
  CompanyType? get typeFilter => _typeFilter;
  bool get includeInactive => _includeInactive;
  
  // 비활성 포함 토글
  void toggleIncludeInactive() {
    _includeInactive = !_includeInactive;
    loadData(isRefresh: true);
  }

  // 계층 구조 getter
  CompanyHierarchy? get companyHierarchy => _companyHierarchy;
  bool get isTreeView => _isTreeView;
  Map<String, bool> get expandedNodes => _expandedNodes;
  
  CompanyListController() {
    if (GetIt.instance.isRegistered<CompanyService>()) {
      _companyService = GetIt.instance<CompanyService>();
      _getCompanyHierarchyUseCase = GetIt.instance<GetCompanyHierarchyUseCase>();
      _updateParentCompanyUseCase = GetIt.instance<UpdateParentCompanyUseCase>();
      _validateCompanyDeletionUseCase = GetIt.instance<ValidateCompanyDeletionUseCase>();
    } else {
      throw Exception('CompanyService not registered in GetIt');
    }
  }

  // 기존 initializeWithPageSize를 사용하는 코드와의 호환성 유지
  Future<void> initializeWithPageSize(int newPageSize) async {
    await initialize(pageSize: newPageSize);
  }

  @override
  Future<PagedResult<CompanyItem>> fetchData({
    required PaginationParams params,
    Map<String, dynamic>? additionalFilters,
  }) async {
    // 실제 본사 개수 병렬 조회 (헤드쿼터 API 기준)
    final headquartersFuture = _loadActualHeadquartersCount();
    
    // API 호출 - 회사 목록 조회 (모든 필드 포함)
    final response = await ErrorHandler.handleApiCall(
      () => _companyService.getCompanies(
        page: params.page,
        perPage: params.perPage,
        search: params.search,
        includeInactive: _includeInactive,
      ),
      onError: (failure) {
        throw failure;
      },
    );
    
    // 병렬 호출 완료 대기
    await headquartersFuture;
    
    if (response == null) {
      return PagedResult(
        items: [],
        meta: PaginationMeta(
          currentPage: params.page,
          perPage: params.perPage,
          total: 0,
          totalPages: 0,
          hasNext: false,
          hasPrevious: false,
        ),
      );
    }
    
    // Company 리스트를 CompanyItem 리스트로 변환 (parentCompanyId 기반 본사/지점 구분)
    final companyItems = await _buildCompanyItems(response.items);
    
    // 🔍 데이터 분석을 위한 상세 로그
    final headquartersInPage = response.items.where((c) => c.parentCompanyId == null).length;
    final branchesInPage = response.items.where((c) => c.parentCompanyId != null).length;
    
    debugPrint('📊 [CompanyListController] 페이지 ${response.page} 데이터 분석:');
    debugPrint('  • 이 페이지 전체 회사: ${response.items.length}개');
    debugPrint('  • 이 페이지 본사 (parentCompanyId == null): $headquartersInPage개');
    debugPrint('  • 이 페이지 지점 (parentCompanyId != null): $branchesInPage개');
    debugPrint('  • 🔥 총 데이터베이스 회사 수: ${response.totalElements}개');
    debugPrint('  • 🔥 헤드쿼터 API 기준 실제 본사: $_actualHeadquartersCount개');
    debugPrint('  • 🔥 계산된 지점 수: ${response.totalElements - _actualHeadquartersCount}개');
    
    // 서버에서 이미 페이지네이션 및 필터링이 완료된 데이터 사용
    final meta = PaginationMeta(
      currentPage: response.page,
      perPage: response.size,
      total: response.totalElements,
      totalPages: response.totalPages,
      hasNext: !response.last,
      hasPrevious: !response.first,
    );
    
    return PagedResult(items: companyItems, meta: meta);
  }
  
  /// 실제 본사 개수 로드 (헤드쿼터 API 사용)
  Future<void> _loadActualHeadquartersCount() async {
    try {
      final result = await _companyService.getHeadquartersWithPagination();
      result.fold(
        (failure) {
          // 실패 시 기본값 유지
          debugPrint('[CompanyListController] Failed to load headquarters count: ${failure.message}');
        },
        (response) {
          _actualHeadquartersCount = response.totalElements; // 페이지네이션 total 값 사용 (55)
          debugPrint('[CompanyListController] 🔥 페이지네이션 기반 실제 본사 개수: $_actualHeadquartersCount (이전: ${response.items.length}개 페이지 아이템)');
        },
      );
    } catch (e) {
      debugPrint('[CompanyListController] Error loading headquarters count: $e');
    }
  }
  
  /// Company 리스트를 CompanyItem으로 변환 (SRP - 단일 책임)
  /// parentCompanyId 기반으로 본사/지점 구분 및 부모회사명 조회
  Future<List<CompanyItem>> _buildCompanyItems(List<Company> companies) async {
    final List<CompanyItem> items = [];
    
    // 부모 회사 ID들을 모아서 한 번에 조회 (성능 최적화)
    final parentCompanyIds = companies
        .where((c) => c.parentCompanyId != null)
        .map((c) => c.parentCompanyId!)
        .toSet()
        .toList();
    
    // 부모 회사명 매핑 테이블 구성
    Map<int, String> parentCompanyNames = {};
    if (parentCompanyIds.isNotEmpty) {
      try {
        // CompanyService에서 회사명 조회 API 활용
        final parentCompanies = await _companyService.getCompanyNames();
        for (final parent in parentCompanies) {
          if (parentCompanyIds.contains(parent.id)) {
            parentCompanyNames[parent.id] = parent.name;
          }
        }
      } catch (e) {
        // 부모 회사명 조회 실패 시 기본값 사용
        for (final id in parentCompanyIds) {
          parentCompanyNames[id] = '알 수 없음';
        }
      }
    }
    
    // CompanyItem 리스트 구성
    for (final company in companies) {
      if (company.parentCompanyId != null) {
        // 지점: 부모 회사명과 함께 생성
        final parentName = parentCompanyNames[company.parentCompanyId] ?? '알 수 없음';
        items.add(CompanyItem.branch(company, parentName));
      } else {
        // 본사: 단순 생성
        items.add(CompanyItem.headquarters(company));
      }
    }
    
    return items;
  }
  
  // 더 이상 사용하지 않는 메서드 - getCompanies() API는 지점 정보를 포함하지 않음
  // /// Company 리스트를 CompanyItem 리스트로 확장 (본사 + 지점)
  // List<CompanyItem> _expandCompaniesAndBranches(List<Company> companies) {
  //   final List<CompanyItem> items = [];
  //   
  //   for (final company in companies) {
  //     // 1. 본사 추가
  //     items.add(CompanyItem.headquarters(company));
  //     
  //     // 2. 지점들 추가
  //     if (company.branches != null && company.branches!.isNotEmpty) {
  //       for (final branch in company.branches!) {
  //         items.add(CompanyItem.branch(branch, company.name, company.id!));
  //       }
  //     }
  //   }
  //   
  //   return items;
  // }

  @override
  bool filterItem(CompanyItem item, String query) {
    final q = query.toLowerCase();
    return item.name.toLowerCase().contains(q) ||
           item.displayName.toLowerCase().contains(q) ||
           (item.contactPhone?.toLowerCase().contains(q) ?? false) ||
           (item.contactEmail?.toLowerCase().contains(q) ?? false) ||
           (item.companyTypes.any((type) => type.name.toLowerCase().contains(q))) ||
           (item.address.toLowerCase().contains(q)) ||
           (item.contactName?.toLowerCase().contains(q) ?? false) ||
           (item.parentCompanyName?.toLowerCase().contains(q) ?? false);
  }

  // 회사 선택/선택 해제
  void toggleSelection(int companyId) {
    if (selectedCompanyIds.contains(companyId)) {
      selectedCompanyIds.remove(companyId);
    } else {
      selectedCompanyIds.add(companyId);
    }
    notifyListeners();
  }

  // 모든 선택 해제
  void clearSelection() {
    selectedCompanyIds.clear();
    notifyListeners();
  }

  // 필터 설정
  void setFilters({bool? isActive, CompanyType? type}) {
    _isActiveFilter = isActive;
    _typeFilter = type;
    loadData(isRefresh: true);
  }

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

  // 회사 추가
  Future<void> addCompany(Company company) async {
    await ErrorHandler.handleApiCall<void>(
      () => _companyService.createCompany(company),
      onError: (failure) {
        throw failure;
      },
    );
    
    await refresh();
  }

  // 회사 수정
  Future<void> updateCompany(Company company) async {
    if (company.id == null) {
      throw Exception('회사 ID가 없습니다');
    }
    
    await ErrorHandler.handleApiCall<void>(
      () => _companyService.updateCompany(company.id!, company),
      onError: (failure) {
        throw failure;
      },
    );
    
    // CompanyItem에서 해당 회사 업데이트
    // TODO: 지역적 업데이트 대신 전체 새로고침 사용
    await refresh();
  }
  
  // DEPRECATED: 지점 관련 메서드들 (계층형 Company 구조로 대체)
  @Deprecated('계층형 Company 구조로 대체되었습니다. 자회사로 생성하려면 parentCompanyId를 설정하세요.')
  Future<void> addBranch(int companyId, Company childCompany) async {
    // 자회사로 생성 (parentCompanyId 설정)
    final companyWithParent = childCompany.copyWith(parentCompanyId: companyId);
    await addCompany(companyWithParent);
  }

  @Deprecated('계층형 Company 구조로 대체되었습니다. updateCompany를 사용하세요.')
  Future<void> updateBranch(int companyId, int branchId, Company company) async {
    await updateCompany(company);
  }
  
  @Deprecated('계층형 Company 구조로 대체되었습니다. deleteCompany를 사용하세요.')
  Future<void> deleteBranch(int companyId, int branchId) async {
    await deleteCompany(branchId);
  }

  // 회사 삭제
  Future<void> deleteCompany(int id) async {
    await ErrorHandler.handleApiCall<void>(
      () => _companyService.deleteCompany(id),
      onError: (failure) {
        throw failure;
      },
    );
    
    // removeItemLocally((c) => c.id == id);  // 로컬 삭제 대신 서버에서 새로고침
    selectedCompanyIds.remove(id);
    
    // 삭제 후 리스트 새로고침 (서버에서 10개 다시 가져오기)
    await refresh();
  }

  // 선택된 회사들 삭제
  Future<void> deleteSelectedCompanies() async {
    for (final id in selectedCompanyIds.toList()) {
      await deleteCompany(id);
    }
    clearSelection();
  }
  
  // ==================== 계층 구조 관련 메서드 ====================
  
  /// Tree View 모드 토글
  void toggleTreeView() {
    _isTreeView = !_isTreeView;
    if (_isTreeView) {
      loadHierarchy();
    } else {
      loadData(isRefresh: true);
    }
  }
  
  /// 계층 구조 로드
  Future<void> loadHierarchy() async {
    isLoadingState = true;
    notifyListeners();
    
    try {
      final result = await _getCompanyHierarchyUseCase.call(
        const GetCompanyHierarchyParams(includeInactive: false),
      );
      
      result.fold(
        (failure) {
          errorState = failure.message;
          _companyHierarchy = null;
        },
        (hierarchy) {
          _companyHierarchy = hierarchy;
          errorState = null;
          // 초기 확장 상태 설정 (루트 노드들만 확장)
          for (final child in hierarchy.children) {
            _expandedNodes[child.id] = true;
          }
        },
      );
    } catch (e) {
      errorState = '계층 구조 로드 중 오류가 발생했습니다: $e';
      _companyHierarchy = null;
    }
    
    isLoadingState = false;
    notifyListeners();
  }
  
  /// 노드 확장/축소 토글
  void toggleNodeExpansion(String nodeId) {
    _expandedNodes[nodeId] = !(_expandedNodes[nodeId] ?? false);
    notifyListeners();
  }
  
  /// 부모 회사 변경
  Future<void> updateParentCompany(int companyId, int? newParentId) async {
    try {
      final result = await _updateParentCompanyUseCase.call(
        UpdateParentCompanyParams(
          companyId: companyId,
          newParentId: newParentId,
        ),
      );
      
      await result.fold(
        (failure) async {
          errorState = failure.message;
          notifyListeners();
        },
        (_) async {
          // 성공적으로 업데이트되면 리스트 새로고침
          if (_isTreeView) {
            await loadHierarchy();
          } else {
            await refresh();
          }
        },
      );
    } catch (e) {
      errorState = '부모 회사 변경 중 오류가 발생했습니다: $e';
      notifyListeners();
    }
  }
  
  /// 회사 삭제 가능 여부 검증
  Future<bool> canDeleteCompany(int companyId) async {
    try {
      final result = await _validateCompanyDeletionUseCase.call(
        ValidateCompanyDeletionParams(companyId: companyId),
      );
      
      return result.fold(
        (failure) {
          errorState = failure.message;
          notifyListeners();
          return false;
        },
        (validationResult) => validationResult.canDelete,
      );
    } catch (e) {
      errorState = '삭제 검증 중 오류가 발생했습니다: $e';
      notifyListeners();
      return false;
    }
  }
}