import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';

import '../../../data/models/equipment/equipment_dto.dart';
import '../../../domain/usecases/equipment/get_equipments_usecase.dart';
import '../../../domain/usecases/equipment/get_equipment_detail_usecase.dart';
import '../../../domain/usecases/equipment/create_equipment_usecase.dart';
import '../../../domain/usecases/equipment/update_equipment_usecase.dart';
import '../../../domain/usecases/equipment/delete_equipment_usecase.dart';
import '../../../domain/usecases/equipment/restore_equipment_usecase.dart';
import '../../../core/constants/app_constants.dart';

@injectable
class EquipmentController with ChangeNotifier {
  final GetEquipmentsUseCase _getEquipmentsUseCase;
  final GetEquipmentDetailUseCase _getEquipmentDetailUseCase;
  final CreateEquipmentUseCase _createEquipmentUseCase;
  final UpdateEquipmentUseCase _updateEquipmentUseCase;
  final DeleteEquipmentUseCase _deleteEquipmentUseCase;
  final RestoreEquipmentUseCase _restoreEquipmentUseCase;

  // 상태 관리
  bool _isLoading = false;
  String? _error;
  List<EquipmentDto> _equipments = [];
  EquipmentDto? _selectedEquipment;
  
  // 페이지네이션
  int _currentPage = 1;
  int _totalPages = 0;
  int _totalItems = 0;
  final int _pageSize = AppConstants.equipmentPageSize;
  
  // 필터
  String? _searchQuery;
  bool _includeDeleted = false;

  EquipmentController(
    this._getEquipmentsUseCase,
    this._getEquipmentDetailUseCase,
    this._createEquipmentUseCase,
    this._updateEquipmentUseCase,
    this._deleteEquipmentUseCase,
    this._restoreEquipmentUseCase,
  );

  // Getters
  bool get isLoading => _isLoading;
  String? get error => _error;
  bool get hasError => _error != null;
  List<EquipmentDto> get equipments => _equipments;
  EquipmentDto? get selectedEquipment => _selectedEquipment;
  int get currentPage => _currentPage;
  int get totalPages => _totalPages;
  int get totalItems => _totalItems;
  int get pageSize => _pageSize;
  String? get searchQuery => _searchQuery;
  bool get includeDeleted => _includeDeleted;

  void _setLoading(bool loading) {
    _isLoading = loading;
    notifyListeners();
  }

  void _setError(String? error) {
    _error = error;
    notifyListeners();
  }

  void clearError() {
    _error = null;
    notifyListeners();
  }

  /// 장비 목록 조회
  Future<void> loadEquipments({
    int page = 1,
    int perPage = AppConstants.equipmentPageSize,
    String? search,
    bool refresh = false,
  }) async {
    try {
      if (refresh) {
        _equipments.clear();
        _currentPage = 1;
        notifyListeners();
      }

      _setLoading(true);
      
      final params = GetEquipmentsParams(
        page: page,
        perPage: perPage,
        search: search,
      );
      
      final response = await _getEquipmentsUseCase(params);
      
      response.fold(
        (failure) => _setError('장비 목록을 불러오는데 실패했습니다: ${failure.message}'),
        (data) {
          _equipments = data.items;
          _currentPage = page;
          _totalPages = data.totalPages;
          _totalItems = data.totalElements;
          _searchQuery = search;
          clearError();
        },
      );
    } catch (e) {
      _setError('장비 목록을 불러오는데 실패했습니다: $e');
    } finally {
      _setLoading(false);
    }
  }

  /// 장비 상세 조회
  Future<void> loadEquipment(int id) async {
    try {
      _setLoading(true);
      
      final response = await _getEquipmentDetailUseCase(id);
      
      response.fold(
        (failure) => _setError('장비 정보를 불러오는데 실패했습니다: ${failure.message}'),
        (equipment) {
          _selectedEquipment = equipment;
          clearError();
        },
      );
    } catch (e) {
      _setError('장비 정보를 불러오는데 실패했습니다: $e');
    } finally {
      _setLoading(false);
    }
  }

  /// 장비 생성
  Future<bool> createEquipment(EquipmentRequestDto request) async {
    try {
      _setLoading(true);
      
      final response = await _createEquipmentUseCase(request);
      
      return response.fold(
        (failure) {
          _setError('장비 생성에 실패했습니다: ${failure.message}');
          return false;
        },
        (equipment) {
          // 목록 새로고침
          loadEquipments(refresh: true);
          clearError();
          return true;
        },
      );
    } catch (e) {
      _setError('장비 생성에 실패했습니다: $e');
      return false;
    } finally {
      _setLoading(false);
    }
  }

  /// 장비 수정
  Future<bool> updateEquipment(int id, EquipmentUpdateRequestDto request) async {
    try {
      _setLoading(true);
      
      final params = UpdateEquipmentParams(id: id, request: request);
      final response = await _updateEquipmentUseCase(params);
      
      return response.fold(
        (failure) {
          _setError('장비 수정에 실패했습니다: ${failure.message}');
          return false;
        },
        (equipment) {
          // 목록 새로고침
          loadEquipments(refresh: true);
          clearError();
          return true;
        },
      );
    } catch (e) {
      _setError('장비 수정에 실패했습니다: $e');
      return false;
    } finally {
      _setLoading(false);
    }
  }

  /// 장비 삭제 (Soft Delete)
  Future<bool> deleteEquipment(int id) async {
    try {
      _setLoading(true);
      
      final response = await _deleteEquipmentUseCase(id);
      
      return response.fold(
        (failure) {
          _setError('장비 삭제에 실패했습니다: ${failure.message}');
          return false;
        },
        (_) {
          // 목록 새로고침
          loadEquipments(refresh: true);
          clearError();
          return true;
        },
      );
    } catch (e) {
      _setError('장비 삭제에 실패했습니다: $e');
      return false;
    } finally {
      _setLoading(false);
    }
  }

  /// 장비 복구
  Future<bool> restoreEquipment(int id) async {
    try {
      _setLoading(true);
      
      final response = await _restoreEquipmentUseCase(id);
      
      return response.fold(
        (failure) {
          _setError('장비 복구에 실패했습니다: ${failure.message}');
          return false;
        },
        (equipment) {
          // 목록 새로고침
          loadEquipments(refresh: true);
          clearError();
          return true;
        },
      );
    } catch (e) {
      _setError('장비 복구에 실패했습니다: $e');
      return false;
    } finally {
      _setLoading(false);
    }
  }

  /// 페이지 변경
  Future<void> goToPage(int page) async {
    if (page < 1 || page > _totalPages || page == _currentPage) return;
    
    await loadEquipments(
      page: page,
      search: _searchQuery,
    );
  }

  /// 검색 설정
  void setSearch(String? search) {
    _searchQuery = search;
    loadEquipments(
      search: search,
      refresh: true,
    );
  }

  /// 새로고침
  Future<void> refresh() async {
    await loadEquipments(
      page: 1,
      search: _searchQuery,
      refresh: true,
    );
  }

  /// 선택된 장비 초기화
  void clearSelectedEquipment() {
    _selectedEquipment = null;
    notifyListeners();
  }
}