Project

General

Profile


home_page.dart history_page.dart connection_page.dart config_page.dart

feeding_page.dart


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

class FeedingPage extends StatefulWidget {
  final String aquariumId;

  const FeedingPage({super.key, required this.aquariumId});

  @override
  State<FeedingPage> createState() => _FeedingPageState();
}

class _FeedingPageState extends State<FeedingPage> {
  bool _isAutoFeedOn = true;
  List<TimeOfDay> _feedTimes = [];
  bool _loading = true;

  late DocumentReference _configRef;

  @override
  void initState() {
    super.initState();
    _configRef = FirebaseFirestore.instance
        .collection('acuarios')
        .doc(widget.aquariumId)
        .collection('data')
        .doc('config');

    _cargarDatos();
  }

  void _cargarDatos() async {
    try {
      DocumentSnapshot doc = await _configRef.get();
      if (doc.exists) {
        Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
        bool estadoSwitch = data['sistema_alimentacion_on'] ?? true;
        List<dynamic> horasString = data['horarios_comida'] ?? [];

        setState(() {
          _isAutoFeedOn = estadoSwitch;
          _feedTimes = horasString.map((s) {
            final parts = s.split(":");
            return TimeOfDay(hour: int.parse(parts[0]), minute: int.parse(parts[1]));
          }).toList();
          _loading = false;
        });
      } else {
        setState(() => _loading = false);
      }
    } catch (e) { setState(() => _loading = false); }
  }

  void _guardarCambios() async {
    List<String> horasString = _feedTimes.map((t) {
      String h = t.hour.toString().padLeft(2, '0');
      String m = t.minute.toString().padLeft(2, '0');
      return "$h:$m";
    }).toList();

    await _configRef.update({
      'horarios_comida': horasString,
      'sistema_alimentacion_on': _isAutoFeedOn 
    });
  }

  Future<void> _addTime() async {
    final TimeOfDay? newTime = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
      builder: (context, child) {
        return Theme(
          data: ThemeData.dark().copyWith(
            colorScheme: const ColorScheme.dark(
              primary: Color(0xFFFF5400),
              onPrimary: Colors.white,
              surface: Color(0xFF001B2E),
            ),
          ),
          child: child!,
        );
      },
    );

    if (newTime != null) {
      setState(() {
        _feedTimes.add(newTime);
        _feedTimes.sort((a, b) => (a.hour * 60 + a.minute).compareTo(b.hour * 60 + b.minute));
      });
      _guardarCambios(); 
    }
  }

  void _removeTime(int index) {
    setState(() {
      _feedTimes.removeAt(index);
    });
    _guardarCambios(); 
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Alimentación', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white)),
        backgroundColor: Colors.transparent,
        iconTheme: const IconThemeData(color: Colors.white),
        elevation: 0,
      ),
      body: _loading 
        ? const Center(child: CircularProgressIndicator(color: Color(0xFFFF5400))) 
        : SingleChildScrollView(
          padding: const EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                decoration: BoxDecoration(
                  color: _isAutoFeedOn ? const Color(0xFFFF5400) : Colors.grey.shade800,
                  borderRadius: BorderRadius.circular(20),
                  border: Border.all(color: Colors.black, width: 3),
                  boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5), blurRadius: 10, offset: const Offset(0, 5))],
                ),
                child: SwitchListTile(
                  contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
                  title: Text(_isAutoFeedOn ? 'Dispensador ACTIVO' : 'Dispensador APAGADO', style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w900, fontSize: 20)),
                  subtitle: Text(_isAutoFeedOn ? 'El sistema alimentará a las horas indicadas.' : 'El sistema NO alimentará.', style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12)),
                  activeColor: Colors.white,
                  activeTrackColor: Colors.black26,
                  value: _isAutoFeedOn,
                  onChanged: (bool value) {
                    setState(() => _isAutoFeedOn = value);
                    _guardarCambios();
                  },
                  secondary: const Icon(Icons.set_meal, color: Colors.white, size: 30),
                ),
              ),
              const SizedBox(height: 30),
              Opacity(
                opacity: _isAutoFeedOn ? 1.0 : 0.5,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text('Horarios Programados', style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold)),
                    const SizedBox(height: 15),
                    ListView.builder(
                      shrinkWrap: true,
                      physics: const NeverScrollableScrollPhysics(),
                      itemCount: _feedTimes.length,
                      itemBuilder: (context, index) {
                        final time = _feedTimes[index];
                        return Container(
                          margin: const EdgeInsets.only(bottom: 10),
                          decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15), border: Border.all(color: const Color(0xFFFF5400), width: 3)),
                          child: ListTile(
                            leading: const Icon(Icons.access_time_filled, color: Colors.black87),
                            title: Text(time.format(context), style: const TextStyle(color: Colors.black87, fontSize: 20, fontWeight: FontWeight.bold)),
                            trailing: IconButton(
                              icon: const Icon(Icons.delete, color: Color(0xFFD32F2F)),
                              onPressed: _isAutoFeedOn ? () => _removeTime(index) : null,
                            ),
                          ),
                        );
                      },
                    ),
                    const SizedBox(height: 20),
                    Center(
                      child: ElevatedButton.icon(
                        onPressed: _isAutoFeedOn ? _addTime : null,
                        style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFFFF5400), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15)),
                        icon: const Icon(Icons.add_alarm),
                        label: const Text('Agregar Horario', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
    );
  }
}