import React, { useState, useMemo } from 'react'; import { View, Text, StyleSheet, ScrollView, Pressable, Image, TextInput, ActivityIndicator } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import Animated, { FadeInRight, FadeInUp } from 'react-native-reanimated'; import { COLORS, SPACING, TYPOGRAPHY, BORDER_RADIUS, SHADOWS } from '../../../constants/theme'; import { Button } from '../../../components/ui/Button'; import { Card } from '../../../components/ui/Card'; import { format, addDays, startOfToday, isSunday, startOfMonth, endOfMonth, eachDayOfInterval, addMonths, isSameDay, isBefore, startOfDay } from 'date-fns'; import { ptBR, es } from 'date-fns/locale'; import { CheckCircle2, ChevronLeft, ChevronRight as ChevronRightIcon, CreditCard, Wallet, Copy, Check, Smartphone } from 'lucide-react-native'; import * as Haptics from 'expo-haptics'; import { useLanguage } from '../../../stores/LanguageContext'; import { useBarbearia } from '../../../stores/BarbeariaContext'; const COMBO_IDS = ['1', '2', '3']; const MORNING_TIMES = ['09:00', '09:30', '10:00', '10:30', '11:00', '11:30']; const AFTERNOON_TIMES = ['13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00']; export default function AgendarScreen() { const { language, t, formatPrice } = useLanguage(); const { barbearia, addAppointment } = useBarbearia(); const colors = barbearia?.colors || COLORS; const services = barbearia?.services || []; const barbers = barbearia?.barbers || []; const [step, setStep] = useState(0); const [clientName, setClientName] = useState(''); const [selectedServices, setSelectedServices] = useState([]); const [selectedBarber, setSelectedBarber] = useState(null); const [isLoading, setIsLoading] = useState(false); const [viewDate, setViewDate] = useState(startOfToday()); const [selectedDate, setSelectedDate] = useState(addDays(startOfToday(), isSunday(startOfToday()) ? 1 : 0)); const [selectedTime, setSelectedTime] = useState(''); const [paymentMethod, setPaymentMethod] = useState(null); const [isCopied, setIsCopied] = useState(false); const dateLocale = language === 'pt' ? ptBR : es; const monthDays = useMemo(() => { const start = startOfMonth(viewDate); const end = endOfMonth(viewDate); return eachDayOfInterval({ start, end }).filter(date => !isSunday(date)); }, [viewDate]); const { totalPt, totalEs, isCombo } = useMemo(() => { const selected = services.filter(s => selectedServices.includes(s.id)); const hasAllCombo = COMBO_IDS.every(id => selectedServices.includes(id)) && COMBO_IDS.length > 0; let subtotalPt = 0; let subtotalEs = 0; selected.forEach(s => { subtotalPt += s.precoPt; subtotalEs += s.precoEs; }); if (hasAllCombo) { return { totalPt: subtotalPt * 0.9, totalEs: subtotalEs * 0.9, isCombo: true }; } return { totalPt: subtotalPt, totalEs: subtotalEs, isCombo: false }; }, [selectedServices, services]); const availablePaymentMethods = useMemo(() => { if (!barbearia) return []; // Filtra pelos métodos habilitados pelo admin let methods = barbearia.paymentMethods || ['money']; // Filtra por regra de negócio do idioma if (language === 'pt') { methods = methods.filter(m => m !== 'alias'); } else { methods = methods.filter(m => m !== 'pix'); } return methods; }, [barbearia, language]); const toggleService = (id: string) => { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); setSelectedServices(prev => prev.includes(id) ? prev.filter(s => s !== id) : [...prev, id]); }; const handleNextStep = () => { Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); setStep(prev => prev + 1); }; const handleBackStep = () => setStep(prev => prev - 1); const handleFinish = async () => { if (!selectedBarber || !selectedTime || !paymentMethod) return; setIsLoading(true); try { await addAppointment({ clientName: clientName || 'Cliente', serviceIds: selectedServices, barberId: selectedBarber, date: format(selectedDate, 'dd/MM/yyyy'), time: selectedTime, totalPt: totalPt, totalEs: totalEs, }); setStep(3); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); } catch (err) { console.error(err); } finally { setIsLoading(false); } }; const copyPixLink = () => { setIsCopied(true); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); setTimeout(() => setIsCopied(false), 2000); }; const isPastTime = (timeStr: string) => { if (!isSameDay(selectedDate, startOfToday())) return false; const [hours, minutes] = timeStr.split(':').map(Number); const now = new Date(); if (hours < now.getHours()) return true; if (hours === now.getHours() && minutes <= now.getMinutes()) return true; return false; }; // Step 0: Services & Barber if (step === 0) { return ( {t('book.services')} {t('lang.subtitle')} Seu Nome {t('home.services')} {services.map((service, idx) => { const isSelected = selectedServices.includes(service.id); return ( toggleService(service.id)} style={[ styles.serviceItem, { backgroundColor: colors.surface, borderColor: colors.divider }, isSelected && { backgroundColor: colors.primary, borderColor: colors.primary, ...(SHADOWS.glow(colors.primary) as any) } ]} > {language === 'pt' ? service.nomePt : service.nomeEs} {service.duracao} min {formatPrice(service.precoPt, service.precoEs)} ); })} {t('home.barbers')} {barbers.map((barber) => ( { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); setSelectedBarber(barber.id); }} style={[ styles.barberItem, { backgroundColor: colors.surface, borderColor: colors.divider }, selectedBarber === barber.id && { backgroundColor: colors.primary, borderColor: colors.primary } ]} > {barber.nome} {selectedBarber === barber.id && } ))} {t('book.total')}: {formatPrice(totalPt, totalEs)}