import 'package:flutter/material.dart';
import 'package:superport/data/models/equipment_history_dto.dart';
import 'package:superport/data/models/stock_status_dto.dart';
import 'package:superport/domain/usecases/equipment_history_usecase.dart';
import 'package:superport/services/equipment_history_service.dart';
import 'package:superport/injection_container.dart';
import 'package:superport/core/constants/app_constants.dart';

class EquipmentHistoryController extends ChangeNotifier {
  final EquipmentHistoryUseCase _useCase = getIt<EquipmentHistoryUseCase>();
  final EquipmentHistoryService _service = EquipmentHistoryService();
  
  // 상태 관리
  bool _isLoading = false;
  bool _isSubmitting = false;
  String? _errorMessage;
  String? _successMessage;
  
  // 데이터 (백엔드 스키마 기반)
  List<EquipmentHistoryDto> _histories = [];
  List<StockStatusDto> _stockStatus = [];
  int _totalCount = 0;
  int _currentPage = 1;
  final int _pageSize = AppConstants.historyPageSize;
  
  // 필터
  int? _filterEquipmentId;
  int? _filterWarehouseId;
  int? _filterCompanyId;
  String? _filterTransactionType;
  String? _filterStartDate;
  String? _filterEndDate;
  String? _searchQuery;
  
  // Getters
  bool get isLoading => _isLoading;
  bool get isSubmitting => _isSubmitting;
  String? get errorMessage => _errorMessage;
  String? get successMessage => _successMessage;
  List<EquipmentHistoryDto> get histories => _histories;
  List<StockStatusDto> get stockStatus => _stockStatus;
  int get totalCount => _totalCount;
  int get currentPage => _currentPage;
  int get pageSize => _pageSize;
  int get totalPages => (_totalCount / _pageSize).ceil();
  
  // 필터 Getters
  int? get filterEquipmentId => _filterEquipmentId;
  int? get filterWarehouseId => _filterWarehouseId;
  int? get filterCompanyId => _filterCompanyId;
  String? get filterTransactionType => _filterTransactionType;
  String? get filterStartDate => _filterStartDate;
  String? get filterEndDate => _filterEndDate;
  String? get searchQuery => _searchQuery;
  
  // 필터 설정
  void setFilters({
    int? equipmentId,
    int? warehouseId,
    int? companyId,
    String? transactionType,
    String? startDate,
    String? endDate,
    String? search,
  }) {
    _filterEquipmentId = equipmentId;
    _filterWarehouseId = warehouseId;
    _filterCompanyId = companyId;
    _filterTransactionType = transactionType;
    _filterStartDate = startDate;
    _filterEndDate = endDate;
    _searchQuery = search;
    _currentPage = 1;
    loadHistories();
  }
  
  // 필터 초기화
  void clearFilters() {
    _filterEquipmentId = null;
    _filterWarehouseId = null;
    _filterCompanyId = null;
    _filterTransactionType = null;
    _filterStartDate = null;
    _filterEndDate = null;
    _searchQuery = null;
    _currentPage = 1;
    loadHistories();
  }
  
  // 페이지 변경
  void changePage(int page) {
    if (page < 1 || page > totalPages) return;
    _currentPage = page;
    loadHistories();
  }
  
  // 재고 이력 목록 조회
  Future<void> loadHistories() async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      final response = await _useCase.getEquipmentHistories(
        page: _currentPage,
        pageSize: _pageSize,
        equipmentsId: _filterEquipmentId,
        warehousesId: _filterWarehouseId,
        companiesId: _filterCompanyId,
        transactionType: _filterTransactionType,
        startDate: _filterStartDate,
        endDate: _filterEndDate,
      );
      
      _histories = response.items;
      _totalCount = response.totalCount;
    } catch (e) {
      _errorMessage = e.toString();
      _histories = [];
      _totalCount = 0;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 특정 장비의 재고 이력 조회
  Future<void> loadEquipmentHistories(int equipmentId) async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      _histories = await _useCase.getEquipmentHistoriesByEquipmentId(equipmentId);
      _totalCount = _histories.length;
    } catch (e) {
      _errorMessage = e.toString();
      _histories = [];
      _totalCount = 0;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 창고별 재고 이력 조회
  Future<void> loadWarehouseHistories(int warehouseId) async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      _histories = await _useCase.getEquipmentHistoriesByWarehouseId(warehouseId);
      _totalCount = _histories.length;
    } catch (e) {
      _errorMessage = e.toString();
      _histories = [];
      _totalCount = 0;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 백엔드 스키마 기반 단순 재고 조회 (EquipmentHistoryDto 기반)
  // 특정 장비의 현재 재고량 계산 (입고량 - 출고량)
  int calculateEquipmentStock(int equipmentId) {
    final equipmentHistories = _histories.where((h) => h.equipmentsId == equipmentId);
    int totalIn = equipmentHistories
        .where((h) => h.transactionType == 'I')
        .fold(0, (sum, h) => sum + h.quantity);
    int totalOut = equipmentHistories
        .where((h) => h.transactionType == 'O')
        .fold(0, (sum, h) => sum + h.quantity);
    return totalIn - totalOut;
  }
  
  // 입고 처리 (백엔드 스키마 기반)
  Future<bool> createStockIn({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    _successMessage = null;
    notifyListeners();
    
    try {
      final request = EquipmentHistoryRequestDto(
        equipmentsId: equipmentsId,
        warehousesId: warehousesId,
        transactionType: 'I', // 입고
        quantity: quantity,
        transactedAt: transactedAt ?? DateTime.now(),
        remark: remark,
      );
      
      await _useCase.createEquipmentHistory(request);
      _successMessage = '입고 처리가 완료되었습니다.';
      await loadHistories();
      return true;
    } catch (e) {
      _errorMessage = e.toString();
      return false;
    } finally {
      _isSubmitting = false;
      notifyListeners();
    }
  }
  
  // 출고 처리 (백엔드 스키마 기반)
  Future<bool> createStockOut({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    _successMessage = null;
    notifyListeners();
    
    try {
      final request = EquipmentHistoryRequestDto(
        equipmentsId: equipmentsId,
        warehousesId: warehousesId,
        transactionType: 'O', // 출고
        quantity: quantity,
        transactedAt: transactedAt ?? DateTime.now(),
        remark: remark,
      );
      
      await _useCase.createEquipmentHistory(request);
      _successMessage = '출고 처리가 완료되었습니다.';
      await loadHistories();
      return true;
    } catch (e) {
      _errorMessage = e.toString();
      return false;
    } finally {
      _isSubmitting = false;
      notifyListeners();
    }
  }
  
  // 백엔드 스키마 기반 단순 통계 기능들
  
  // 특정 창고의 재고 현황 (장비별 집계)
  Map<int, int> getWarehouseStock(int warehouseId) {
    Map<int, int> stockMap = {};
    final warehouseHistories = _histories.where((h) => h.warehousesId == warehouseId);
    
    for (var equipmentId in warehouseHistories.map((h) => h.equipmentsId).toSet()) {
      stockMap[equipmentId] = calculateEquipmentStock(equipmentId);
    }
    return stockMap;
  }
  
  // 전체 재고 현황 요약
  Map<String, int> getStockSummary() {
    int totalIn = _histories
        .where((h) => h.transactionType == 'I')
        .fold(0, (sum, h) => sum + h.quantity);
    int totalOut = _histories
        .where((h) => h.transactionType == 'O')
        .fold(0, (sum, h) => sum + h.quantity);
        
    return {
      'totalStock': totalIn - totalOut,
      'totalIn': totalIn,
      'totalOut': totalOut,
    };
  }
  
  /// 재고 현황 조회 (핵심 기능)
  Future<void> loadStockStatus() async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      _stockStatus = await _service.getStockStatus();
    } catch (e) {
      _errorMessage = e.toString();
      _stockStatus = [];
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 메시지 클리어
  void clearMessages() {
    _errorMessage = null;
    _successMessage = null;
    notifyListeners();
  }
  
  @override
  void dispose() {
    _histories.clear();
    _stockStatus.clear();
    super.dispose();
  }
}