import React, { useState, useEffect, useCallback } from 'react'; import { StyleSheet, View, Text, TouchableOpacity, ActivityIndicator, ScrollView, useWindowDimensions, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { BarChart } from 'react-native-gifted-charts'; const API_BASE_URL = 'https://solorpower.dadot.net'; export default function ComparisonScreen({ navigation }) { const [period, setPeriod] = useState('day'); const [statsData, setStatsData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [currentDate, setCurrentDate] = useState(new Date()); const { width } = useWindowDimensions(); useEffect(() => { setCurrentDate(new Date()); }, [period]); const moveDate = (direction) => { const newDate = new Date(currentDate); if (period === 'day') { newDate.setDate(newDate.getDate() + direction); } else if (period === 'month') { newDate.setMonth(newDate.getMonth() + direction); } else if (period === 'year') { newDate.setFullYear(newDate.getFullYear() + direction); } setCurrentDate(newDate); }; const formatDateDisplay = () => { const y = currentDate.getFullYear(); const m = currentDate.getMonth() + 1; const d = currentDate.getDate(); if (period === 'day') return `${y}년 ${m}월 ${d}일`; if (period === 'month') return `${y}년 ${m}월`; if (period === 'year') return `${y}년`; return ''; }; const fetchStats = useCallback(async () => { try { setLoading(true); setError(null); const y = currentDate.getFullYear(); const m = currentDate.getMonth() + 1; const d = currentDate.getDate(); const dateStr = `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`; let query = `period=${period}`; if (period === 'day') { query += `&date=${dateStr}`; } else if (period === 'month') { query += `&year=${y}&month=${m}`; } else if (period === 'year') { query += `&year=${y}`; } const response = await fetch(`${API_BASE_URL}/plants/stats/comparison?${query}`); if (!response.ok) throw new Error(`HTTP Error: ${response.status}`); const result = await response.json(); setStatsData(result.data || []); } catch (err) { setError(err.message); setStatsData([]); } finally { setLoading(false); } }, [period, currentDate]); useEffect(() => { fetchStats(); }, [fetchStats]); // Chart Data Preparation const chartData = statsData.map(item => { let label = item.plant_name; const match = label.match(/(\d+호기)/); if (match) { label = match[1]; } else { label = label.replace(/태양과바람|발전소/g, '').trim(); } return { value: item.generation, label: label, frontColor: '#3B82F6', topLabelComponent: () => ( {item.generation.toFixed(0)} ), }; }); const renderTabs = () => ( {['day', 'month', 'year'].map((p) => ( setPeriod(p)} > {p === 'day' ? '일간' : p === 'month' ? '월간' : '연간'} ))} ); const renderDateControl = () => ( moveDate(-1)} style={styles.arrowButton}> {formatDateDisplay()} moveDate(1)} style={styles.arrowButton}> ); const renderTable = () => ( 발전소 발전량 용량 시간 {statsData.map((item, index) => ( {item.plant_name} {item.generation.toFixed(1)} {item.capacity} {item.generation_hours.toFixed(2)} ))} {statsData.length === 0 && ( 데이터가 없습니다 )} ); const chartWidth = width - 40; return ( navigation.goBack()}> ← 뒤로 전체 발전소 비교 {renderDateControl()} {renderTabs()} {loading ? ( 데이터 불러오는 중... ) : error ? ( 데이터 조회 실패 {error} 다시 시도 ) : ( <> 📊 발전량 비교 (kWh) {statsData.length > 0 ? ( ) : ( 표시할 데이터가 없습니다. )} 📋 상세 현황 시간 = 발전량 / 설비용량 {period === 'year' ? '/ 365' : ''} {renderTable()} )} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F3F4F6', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', backgroundColor: '#1E40AF', padding: 16, }, backButton: { padding: 8, }, backButtonText: { color: '#FFFFFF', fontSize: 16, fontWeight: '500', }, headerTitle: { fontSize: 18, fontWeight: 'bold', color: '#FFFFFF', }, content: { flex: 1, }, scrollContent: { padding: 16, paddingBottom: 40, }, dateControl: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: 16, gap: 16, }, arrowButton: { padding: 8, }, arrowText: { fontSize: 20, color: '#4B5563', }, dateText: { fontSize: 18, fontWeight: 'bold', color: '#1F2937', }, tabContainer: { flexDirection: 'row', backgroundColor: '#FFFFFF', borderRadius: 12, padding: 4, marginBottom: 16, shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 4, elevation: 2, }, tab: { flex: 1, paddingVertical: 10, alignItems: 'center', borderRadius: 8, }, tabActive: { backgroundColor: '#3B82F6', }, tabText: { fontSize: 14, fontWeight: '600', color: '#6B7280', }, tabTextActive: { color: '#FFFFFF', }, loadingContainer: { height: 300, justifyContent: 'center', alignItems: 'center', }, loadingText: { marginTop: 12, color: '#6B7280', }, errorContainer: { height: 300, justifyContent: 'center', alignItems: 'center', }, errorText: { fontSize: 16, color: '#EF4444', marginBottom: 8, }, errorDetail: { fontSize: 12, color: '#6B7280', marginBottom: 16, }, retryButton: { backgroundColor: '#3B82F6', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8, }, retryButtonText: { color: '#FFFFFF', }, chartSection: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 16, marginBottom: 16, shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 8, elevation: 2, }, sectionTitle: { fontSize: 16, fontWeight: 'bold', color: '#1F2937', marginBottom: 12, }, chartContainer: { alignItems: 'center', paddingVertical: 10, }, noDataText: { color: '#9CA3AF', marginVertical: 20, }, tableSection: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 16, shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 8, elevation: 2, }, tableHeaderRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, }, unitText: { fontSize: 11, color: '#6B7280', }, table: { borderWidth: 1, borderColor: '#E5E7EB', borderRadius: 8, overflow: 'hidden', }, tableHeader: { flexDirection: 'row', backgroundColor: '#F3F4F6', paddingVertical: 10, paddingHorizontal: 8, borderBottomWidth: 1, borderBottomColor: '#E5E7EB', }, columnHeader: { fontSize: 12, fontWeight: 'bold', color: '#4B5563', textAlign: 'center', }, tableRow: { flexDirection: 'row', paddingVertical: 12, paddingHorizontal: 8, borderBottomWidth: 1, borderBottomColor: '#E5E7EB', }, tableRowAlt: { backgroundColor: '#F9FAFB', }, cell: { fontSize: 12, color: '#1F2937', textAlign: 'center', }, emptyRow: { padding: 20, alignItems: 'center', }, emptyText: { color: '#9CA3AF', fontSize: 14, }, });