import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import '../../../data/models/equipment_history_dto.dart';
import '../../../domain/usecases/equipment_history_usecase.dart';
import '../../../core/constants/app_constants.dart';

class EquipmentHistoryController extends ChangeNotifier {
  final EquipmentHistoryUseCase _useCase;
  
  EquipmentHistoryController({
    EquipmentHistoryUseCase? useCase,
  }) : _useCase = useCase ?? GetIt.instance<EquipmentHistoryUseCase>();
  
  // 상태 변수 (백엔드 스키마 기반)
  List<EquipmentHistoryDto> _historyList = [];
  bool _isLoading = false;
  String? _error;
  
  // 페이지네이션
  int _currentPage = 1;
  int _pageSize = AppConstants.historyPageSize;
  int _totalCount = 0;
  
  // 필터 (백엔드 실제 필드만)
  String _searchQuery = '';
  String? _transactionType;
  int? _warehouseId;
  int? _equipmentId;
  DateTime? _startDate;
  DateTime? _endDate;
  
  // Getters (백엔드 실제 데이터만)
  List<EquipmentHistoryDto> get historyList => _historyList;
  bool get isLoading => _isLoading;
  String? get error => _error;
  int get currentPage => _currentPage;
  int get totalPages => (_totalCount / _pageSize).ceil();
  int get totalCount => _totalCount;
  String get searchQuery => _searchQuery;
  
  // 간단한 통계 (백엔드 실제 데이터 기반)
  int get totalTransactions => _historyList.length;
  int get totalInQuantity => _historyList
      .where((item) => item.transactionType == 'I')
      .fold(0, (sum, item) => sum + item.quantity);
  int get totalOutQuantity => _historyList
      .where((item) => item.transactionType == 'O')
      .fold(0, (sum, item) => sum + item.quantity);
  
  // 재고 이력 조회
  Future<void> loadHistory({bool refresh = false}) async {
    if (refresh) {
      _currentPage = 1;
      _historyList.clear();
    }
    
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final result = await _useCase.getEquipmentHistories(
        page: _currentPage,
        pageSize: _pageSize,
        transactionType: _transactionType,
        warehousesId: _warehouseId,
        equipmentsId: _equipmentId,
        startDate: _startDate?.toIso8601String(),
        endDate: _endDate?.toIso8601String(),
      );
      
      // result는 EquipmentHistoryListResponse 타입으로 Either가 아님
      if (refresh) {
        _historyList = result.items;
      } else {
        _historyList.addAll(result.items);
      }
      _totalCount = result.totalCount;
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 백엔드 스키마 기반 단순 재고 조회 (EquipmentHistoryDto 기반)
  // 특정 장비의 현재 재고량 계산 (입고량 - 출고량)
  int calculateEquipmentStock(int equipmentId) {
    final equipmentHistories = _historyList.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;
  }
  
  // 백엔드 스키마 기반 단순 필터링
  void setFilters({
    String? transactionType,
    int? warehouseId,
    int? equipmentId,
    DateTime? startDate,
    DateTime? endDate,
    String? searchQuery,
  }) {
    _transactionType = transactionType;
    _warehouseId = warehouseId;
    _equipmentId = equipmentId;
    _startDate = startDate;
    _endDate = endDate;
    if (searchQuery != null) _searchQuery = searchQuery;
    
    _currentPage = 1;
    loadHistory(refresh: true);
  }
  
  void clearFilters() {
    _transactionType = null;
    _warehouseId = null;
    _equipmentId = null;
    _startDate = null;
    _endDate = null;
    _searchQuery = '';
    
    _currentPage = 1;
    loadHistory(refresh: true);
  }
  
  // 백엔드 스키마 기반 단순 통계
  Map<String, int> getStockSummary() {
    int totalIn = _historyList
        .where((h) => h.transactionType == 'I')
        .fold(0, (sum, h) => sum + h.quantity);
    int totalOut = _historyList
        .where((h) => h.transactionType == 'O')
        .fold(0, (sum, h) => sum + h.quantity);
        
    return {
      'totalStock': totalIn - totalOut,
      'totalIn': totalIn,
      'totalOut': totalOut,
    };
  }
  
  // 입고 처리 (백엔드 스키마 기반)
  Future<bool> createStockIn({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final request = EquipmentHistoryRequestDto(
        equipmentsId: equipmentsId,
        warehousesId: warehousesId,
        transactionType: 'I', // 입고
        quantity: quantity,
        transactedAt: transactedAt ?? DateTime.now(),
        remark: remark,
      );
      
      await _useCase.createEquipmentHistory(request);
      await loadHistory(refresh: true);
      return true;
    } catch (e) {
      _error = e.toString();
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 출고 처리 (백엔드 스키마 기반)
  Future<bool> createStockOut({
    required int equipmentsId,
    required int warehousesId,
    required int quantity,
    DateTime? transactedAt,
    String? remark,
  }) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final request = EquipmentHistoryRequestDto(
        equipmentsId: equipmentsId,
        warehousesId: warehousesId,
        transactionType: 'O', // 출고
        quantity: quantity,
        transactedAt: transactedAt ?? DateTime.now(),
        remark: remark,
      );
      
      await _useCase.createEquipmentHistory(request);
      await loadHistory(refresh: true);
      return true;
    } catch (e) {
      _error = e.toString();
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // createHistory 메서드 (별칭)
  Future<bool> createHistory(EquipmentHistoryRequestDto request) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      await _useCase.createEquipmentHistory(request);
      await loadHistory(refresh: true);
      return true;
    } catch (e) {
      _error = e.toString();
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // searchEquipmentHistories 메서드
  Future<List<EquipmentHistoryDto>> searchEquipmentHistories({
    String? query,
    String? transactionType,
    int? equipmentId,
    int? warehouseId,
  }) async {
    try {
      final result = await _useCase.getEquipmentHistories(
        page: 1,
        pageSize: AppConstants.bulkPageSize,
        transactionType: transactionType,
        equipmentsId: equipmentId,
        warehousesId: warehouseId,
      );
      
      List<EquipmentHistoryDto> histories = result.items;
      
      // 간단한 텍스트 검색 (remark 필드 기반)
      if (query != null && query.isNotEmpty) {
        histories = histories.where((h) => 
          h.remark?.toLowerCase().contains(query.toLowerCase()) ?? false
        ).toList();
      }
      
      return histories;
    } catch (e) {
      _error = e.toString();
      notifyListeners();
      return [];
    }
  }

  // setSearchQuery 메서드
  void setSearchQuery(String query) {
    _searchQuery = query;
    setFilters(searchQuery: query);
  }

  // loadInventoryStatus 메서드 (단순 재고 상태 로드)
  Future<void> loadInventoryStatus() async {
    await loadHistory(refresh: true);
  }

  // loadWarehouseStock 메서드 (창고별 재고 로드)
  Future<void> loadWarehouseStock({int? warehouseId}) async {
    setFilters(warehouseId: warehouseId);
  }

  // getAvailableStock 메서드
  Future<int> getAvailableStock(int equipmentId, {int? warehouseId}) async {
    try {
      final result = await _useCase.getEquipmentHistories(
        page: 1,
        pageSize: AppConstants.maxBulkPageSize,
        equipmentsId: equipmentId,
        warehousesId: warehouseId,
      );
      
      int totalIn = result.items
          .where((h) => h.transactionType == 'I')
          .fold(0, (sum, h) => sum + h.quantity);
      int totalOut = result.items
          .where((h) => h.transactionType == 'O')
          .fold(0, (sum, h) => sum + h.quantity);
      
      return totalIn - totalOut;
    } catch (e) {
      return 0;
    }
  }

  // getAvailableEquipments 메서드 (사용 가능한 장비 목록)
  Future<List<int>> getAvailableEquipments({int? warehouseId}) async {
    try {
      final result = await _useCase.getEquipmentHistories(
        page: 1,
        pageSize: AppConstants.maxBulkPageSize,
        warehousesId: warehouseId,
      );
      
      // 재고가 있는 장비 ID들만 반환
      Map<int, int> stockMap = {};
      for (var history in result.items) {
        stockMap[history.equipmentsId] = (stockMap[history.equipmentsId] ?? 0) +
            (history.transactionType == 'I' ? history.quantity : -history.quantity);
      }
      
      return stockMap.entries
          .where((entry) => entry.value > 0)
          .map((entry) => entry.key)
          .toList();
    } catch (e) {
      return [];
    }
  }

  // 페이지네이션 메서드들
  Future<void> previousPage() async {
    if (_currentPage > 1) {
      _currentPage--;
      await loadHistory();
    }
  }

  Future<void> nextPage() async {
    if (_currentPage < totalPages) {
      _currentPage++;
      await loadHistory();
    }
  }

  // 에러 클리어
  void clearError() {
    _error = null;
    notifyListeners();
  }
  
  @override
  void dispose() {
    _historyList.clear();
    super.dispose();
  }
}