import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:get_it/get_it.dart'; import 'package:superport/data/models/equipment/equipment_history_dto.dart'; import 'package:superport/services/equipment_service.dart'; import 'package:superport/screens/common/custom_widgets.dart'; import 'package:superport/core/errors/failures.dart'; import 'package:intl/intl.dart'; class EquipmentHistoryScreen extends StatefulWidget { final int equipmentId; final String equipmentName; const EquipmentHistoryScreen({ Key? key, required this.equipmentId, required this.equipmentName, }) : super(key: key); @override State createState() => _EquipmentHistoryScreenState(); } class _EquipmentHistoryScreenState extends State { final EquipmentService _equipmentService = GetIt.instance(); List _histories = []; bool _isLoading = true; String? _error; int _currentPage = 1; final int _perPage = 20; bool _hasMore = true; final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); _loadHistory(); _scrollController.addListener(_onScroll); } @override void dispose() { _scrollController.dispose(); super.dispose(); } void _onScroll() { if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 200) { _loadMoreHistory(); } } Future _loadHistory({bool isRefresh = false}) async { if (isRefresh) { _currentPage = 1; _hasMore = true; _histories.clear(); } if (!_hasMore || (!isRefresh && _isLoading)) return; setState(() { _isLoading = true; _error = null; }); try { final histories = await _equipmentService.getEquipmentHistory( widget.equipmentId, page: _currentPage, perPage: _perPage, ); setState(() { if (isRefresh) { _histories = histories; } else { _histories.addAll(histories); } _hasMore = histories.length == _perPage; if (_hasMore) _currentPage++; _isLoading = false; }); } on Failure catch (e) { setState(() { _error = e.message; _isLoading = false; }); } catch (e) { setState(() { _error = '이력을 불러오는 중 오류가 발생했습니다: $e'; _isLoading = false; }); } } Future _loadMoreHistory() async { await _loadHistory(); } String _formatDate(DateTime? date) { if (date == null) return '-'; return DateFormat('yyyy-MM-dd HH:mm').format(date); } String _getTransactionTypeText(String? type) { switch (type) { case 'I': return '입고'; case 'O': return '출고'; case 'R': return '대여'; case 'T': return '반납'; case 'D': return '폐기'; default: return type ?? '-'; } } Color _getTransactionTypeColor(String? type) { switch (type) { case 'I': return Colors.green; case 'O': return Colors.blue; case 'R': return Colors.orange; case 'T': return Colors.teal; case 'D': return Colors.red; default: return Colors.grey; } } Widget _buildHistoryItem(EquipmentHistoryDto history) { final typeColor = _getTransactionTypeColor(history.transactionType); return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: ListTile( leading: CircleAvatar( backgroundColor: typeColor.withOpacity(0.2), child: Text( _getTransactionTypeText(history.transactionType), style: TextStyle( color: typeColor, fontWeight: FontWeight.bold, fontSize: 12, ), ), ), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( history.remarks ?? '비고 없음', overflow: TextOverflow.ellipsis, ), ), Text( '수량: ${history.quantity}', style: const TextStyle(fontSize: 14), ), ], ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), Text(_formatDate(history.transactionDate)), if (history.userName != null) Text('담당자: ${history.userName}'), ], ), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('장비 이력'), Text( widget.equipmentName, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.normal), ), ], ), ), body: _isLoading && _histories.isEmpty ? const Center(child: CircularProgressIndicator()) : _error != null && _histories.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(_error!, style: const TextStyle(color: Colors.red)), const SizedBox(height: 16), ElevatedButton( onPressed: () => _loadHistory(isRefresh: true), child: const Text('다시 시도'), ), ], ), ) : RefreshIndicator( onRefresh: () => _loadHistory(isRefresh: true), child: _histories.isEmpty ? ListView( children: const [ SizedBox(height: 200), Center( child: Text( '이력이 없습니다.', style: TextStyle(fontSize: 16, color: Colors.grey), ), ), ], ) : ListView.builder( controller: _scrollController, itemCount: _histories.length + (_hasMore ? 1 : 0), itemBuilder: (context, index) { if (index == _histories.length) { return const Padding( padding: EdgeInsets.all(16.0), child: Center(child: CircularProgressIndicator()), ); } return _buildHistoryItem(_histories[index]); }, ), ), ); } }