import 'package:flutter/material.dart'; import 'package:injectable/injectable.dart'; import '../../../core/constants/app_constants.dart'; import '../../../data/models/rent_dto.dart'; import '../../../domain/usecases/rent_usecase.dart'; @injectable class RentController with ChangeNotifier { final RentUseCase _rentUseCase; // 상태 관리 (단순화) bool _isLoading = false; String? _error; List _rents = []; // 단순한 List 구조 RentDto? _selectedRent; // 필터링 상태 String? _selectedStatus; int? _selectedEquipmentHistoryId; RentController(this._rentUseCase); // Getters (단순화) bool get isLoading => _isLoading; String? get error => _error; bool get hasError => _error != null; RentDto? get selectedRent => _selectedRent; String? get selectedStatus => _selectedStatus; int? get selectedEquipmentHistoryId => _selectedEquipmentHistoryId; // 편의 메서드 (백엔드 실제 구조) List get rents => _rents; int get totalRents => _rents.length; // 페이징 관련 getter (UI 호환성) int get currentPage => 1; // 단순화된 페이징 구조 int get totalPages => (_rents.length / AppConstants.rentPageSize).ceil(); int get totalItems => _rents.length; void _setLoading(bool loading) { _isLoading = loading; notifyListeners(); } void _setError(String? error) { _error = error; notifyListeners(); } void clearError() { _error = null; notifyListeners(); } /// 임대 목록 조회 (백엔드 실제 파라미터) Future loadRents({ int page = 1, int perPage = AppConstants.rentPageSize, int? equipmentId, int? companyId, bool? isActive, DateTime? dateFrom, DateTime? dateTo, bool refresh = false, }) async { try { if (refresh) { _rents.clear(); notifyListeners(); } _setLoading(true); final response = await _rentUseCase.getRents( page: page, perPage: perPage, equipmentId: equipmentId, companyId: companyId, isActive: isActive, dateFrom: dateFrom, dateTo: dateTo, ); // 올바른 RentListResponse.items 접근 _rents = response.items; clearError(); } catch (e) { _setError('임대 목록을 불러오는데 실패했습니다: $e'); } finally { _setLoading(false); } } /// 임대 상세 조회 Future loadRent(int id) async { try { _setLoading(true); final response = await _rentUseCase.getRent(id); _selectedRent = response; // response가 직접 RentDto clearError(); } catch (e) { _setError('임대 상세 정보를 불러오는데 실패했습니다: $e'); } finally { _setLoading(false); } } /// 임대 생성 (백엔드 실제 스키마) Future createRent({ required int equipmentHistoryId, required DateTime startedAt, required DateTime endedAt, }) async { try { _setLoading(true); await _rentUseCase.createRent( RentRequestDto( equipmentHistoryId: equipmentHistoryId, startedAt: startedAt, endedAt: endedAt, ), ); // 목록 새로고침 await loadRents(refresh: true); clearError(); return true; } catch (e) { _setError('임대 생성에 실패했습니다: $e'); return false; } finally { _setLoading(false); } } /// 임대 수정 (백엔드 실제 스키마) Future updateRent({ required int id, DateTime? startedAt, DateTime? endedAt, }) async { try { _setLoading(true); await _rentUseCase.updateRent( id, RentUpdateRequestDto( startedAt: startedAt, endedAt: endedAt, ), ); // 목록 새로고침 await loadRents(refresh: true); clearError(); return true; } catch (e) { _setError('임대 수정에 실패했습니다: $e'); return false; } finally { _setLoading(false); } } /// 임대 삭제 Future deleteRent(int id) async { try { _setLoading(true); await _rentUseCase.deleteRent(id); // 목록 새로고침 await loadRents(refresh: true); clearError(); return true; } catch (e) { _setError('임대 삭제에 실패했습니다: $e'); return false; } finally { _setLoading(false); } } // 백엔드에서 반납/연장 처리는 endedAt 수정으로 처리 Future updateRentEndDate(int id, DateTime newEndDate) async { return await updateRent( id: id, endedAt: newEndDate, ); } /// 진행중인 임대 조회 (백엔드 실존 API) Future loadActiveRents() async { try { _setLoading(true); final activeRents = await _rentUseCase.getActiveRents(); _rents = activeRents; clearError(); } catch (e) { _setError('진행중인 임대를 불러오는데 실패했습니다: $e'); } finally { _setLoading(false); } } /// 장비별 임대 조회 (백엔드 필터링) Future loadRentsByEquipment(int equipmentId) async { try { _setLoading(true); final equipmentRents = await _rentUseCase.getRentsByEquipment(equipmentId); _rents = equipmentRents; clearError(); } catch (e) { _setError('장비별 임대를 불러오는데 실패했습니다: $e'); } finally { _setLoading(false); } } /// 필터 초기화 void clearFilters() { _selectedStatus = null; _selectedEquipmentHistoryId = null; notifyListeners(); } /// 장비 이력 필터 설정 (UI 호환성) void setEquipmentHistoryFilter(int? equipmentHistoryId) { _selectedEquipmentHistoryId = equipmentHistoryId; notifyListeners(); } /// 선택된 임대 초기화 void clearSelectedRent() { _selectedRent = null; notifyListeners(); } // 백엔드 계산 필드 활용 (강력한 기능) String getRentStatus(RentDto rent) { // 백엔드에서 계산된 is_active 필드 활용 if (rent.isActive == true) return '진행중'; // 날짜 기반 판단 (Fallback) final now = DateTime.now(); if (rent.startedAt.isAfter(now)) return '예약'; if (rent.endedAt.isBefore(now)) return '종료'; return '진행중'; } // 백엔드에서 계산된 남은 일수 활용 int getRemainingDays(RentDto rent) { return rent.daysRemaining ?? 0; } // 백엔드에서 계산된 총 일수 활용 int getTotalDays(RentDto rent) { return rent.totalDays ?? 0; } // UI 호환성을 위한 상태 표시명 String getRentStatusDisplayName(String status) { switch (status.toLowerCase()) { case '예약': case 'reserved': return '예약'; case '진행중': case 'active': return '진행중'; case '종료': case 'completed': return '종료'; default: return status; } } /// 새로고침 Future refresh() async { await loadRents(refresh: true); } /// 임대 반납 처리 (백엔드 PUT API 활용) Future returnRent(int id) async { return await updateRent( id: id, endedAt: DateTime.now(), ); } /// 상태 필터 설정 (UI 호환성) void setStatusFilter(String? status) { _selectedStatus = status; notifyListeners(); } /// 임대 기간 계산 (UI 호환성) int calculateRentDays(DateTime startDate, DateTime endDate) { return endDate.difference(startDate).inDays; } /// 임대 총 비용 계산 (문자열 날짜 기반) double calculateTotalRent(String startDate, String endDate, double dailyRate) { try { final start = DateTime.parse(startDate); final end = DateTime.parse(endDate); final days = end.difference(start).inDays; return days * dailyRate; } catch (e) { return 0.0; } } }