import 'package:blind_master/BlindMasterResources/error_snackbar.dart';
import 'package:blind_master/BlindMasterResources/secure_transmissions.dart';
import 'package:blind_master/main.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

class DayTimePicker extends StatefulWidget {
  const DayTimePicker({
    super.key,
    required this.defaultTime,
    required this.sendSchedule,
    this.peripheralId,
    this.peripheralNum,
    this.deviceId,
    this.groupId,
    this.existingSchedule,
    this.scheduleId,
  });

  final TimeOfDay defaultTime;
  final void Function(TimeOfDay) sendSchedule;
  final int? peripheralId;
  final int? peripheralNum;
  final int? deviceId;
  final int? groupId;
  final Map<String, dynamic>? existingSchedule;
  final String? scheduleId;
  
  bool get isEditing => existingSchedule != null && scheduleId != null;
  bool get isGroupMode => groupId != null;
  
  @override
  State<DayTimePicker> createState() => _DayTimePickerState();
}

class _DayTimePickerState extends State<DayTimePicker> {
  TimeOfDay? scheduleTime;
  double _blindPosition = 0;
  String imagePath = "";
  Set<DaysOfWeek> days = <DaysOfWeek>{};
  bool showError = false;

  @override
  void initState() {
    super.initState();
    
    // If editing, pre-populate with existing schedule data
    if (widget.isEditing && widget.existingSchedule != null) {
      final schedule = widget.existingSchedule!;
      final hour = schedule['schedule']['hours'][0] as int;
      final minute = schedule['schedule']['minutes'][0] as int;
      scheduleTime = TimeOfDay(hour: hour, minute: minute);
      _blindPosition = (schedule['pos'] as int).toDouble();
      
      // Pre-populate days
      final daysOfWeek = schedule['schedule']['daysOfWeek'] as List;
      days = daysOfWeek.map((d) => DaysOfWeek.values[d as int]).toSet();
    }
    
    updateBackground();
  }

  Future selectTime() async {
    scheduleTime = await showTimePicker(
      context: context,
      initialTime: scheduleTime ?? widget.defaultTime,
    ) ?? (scheduleTime ?? widget.defaultTime);
    setState(() {
      updateBackground();
    });
  }

  void updateBackground() {
    final hour = scheduleTime?.hour ?? widget.defaultTime.hour;
  
    if (hour >= 5 && hour < 10) {
      imagePath = 'assets/images/MorningSill.png';
    } else if (hour >= 10 && hour < 18) {
      imagePath = 'assets/images/NoonSill.png';
    } else if (hour >= 18 && hour < 22) {
      imagePath = 'assets/images/EveningSill.png';
    } else {
      imagePath = 'assets/images/NightSill.png';
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(
        (widget.isEditing) ? 'Edit Schedule' : 'New Schedule',
        style: GoogleFonts.aBeeZee(),
      ),
      content: Column(
        mainAxisSize: MainAxisSize.min, // Keep column compact
        children: <Widget>[
          Text(
            "Move to position"
          ),
          SizedBox(
            height: MediaQuery.of(context).size.height * 0.3,
            child: Container(
              padding: EdgeInsets.fromLTRB(0, 20, 0, 20),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SizedBox(
                    width: MediaQuery.of(context).size.width * 0.11,
                  ),
                  Stack(
                    children: [
                      // Background image
                      Align(
                        alignment: Alignment.center,
                        child: Image.asset(
                          imagePath,
                          // fit: BoxFit.cover,
                          width: MediaQuery.of(context).size.width * 0.45,
                        ),
                      ),

                      Align(
                        alignment: Alignment.center,
                        child: Builder(
                          builder: (context) {
                            final containerHeight = MediaQuery.of(context).size.width * 0.43;
                            final maxSlatHeight = containerHeight / 10;
                            final slatHeight = _blindPosition < 5 
                              ? maxSlatHeight * (5 - _blindPosition) / 5
                              : maxSlatHeight * (_blindPosition - 5) / 5;
                            
                            return Container(
                              margin: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.05),
                              height: containerHeight,
                              width: MediaQuery.of(context).size.width * 0.45,
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: List.generate(10, (index) {
                                  return AnimatedContainer(
                                    duration: const Duration(milliseconds: 300),
                                    height: slatHeight,
                                    width: MediaQuery.of(context).size.width * 0.40,
                                    color: const Color.fromARGB(255, 121, 85, 72),
                                  );
                                }),
                              ),
                            );
                          }
                        )
                      ),
                    ],
                  ),
                  // Slider on the side
                  SizedBox(
                    width: MediaQuery.of(context).size.width * 0.10,
                    child: RotatedBox(
                      quarterTurns: -1,
                      child: Slider(
                        value: _blindPosition,
                        activeColor: Theme.of(context).primaryColorDark,
                        thumbColor: Theme.of(context).primaryColorLight,
                        inactiveColor: Theme.of(context).primaryColorDark,
                        min: 0,
                        max: 10,
                        divisions: 10,
                        onChanged: (value) {
                          setState(() {
                            _blindPosition = value;
                          });
                        },
                      ),
                    ),
                  )
                ],
              ),
            )
          ),
          Text(
            "At"
          ),
          Theme(
            data: Theme.of(context).copyWith(
              timePickerTheme: TimePickerThemeData(
                hourMinuteColor: Theme.of(context).primaryColorDark,
                dialBackgroundColor: Theme.of(context).primaryColorDark,
              )
            ),
            child: ElevatedButton(
              onPressed: selectTime,
              style: ElevatedButton.styleFrom(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10)
                ),
                backgroundColor: Theme.of(context).primaryColorDark,
                foregroundColor: Theme.of(context).highlightColor
              ),
              child: Text(scheduleTime?.format(context) ?? widget.defaultTime.format(context)),
            ),
          ),
          Container(
            padding: EdgeInsets.all(10),
            child: Text(
              "Every"
            ),
          ),
          Wrap(
            spacing: 5.0,
            alignment: WrapAlignment.center,
            children: DaysOfWeek.values.map((DaysOfWeek day) {
              return FilterChip(
                showCheckmark: false,
                label: Text(day.name),
                selected: days.contains(day),
                selectedColor: Theme.of(context).primaryColorDark,
                onSelected: (bool selected) {
                  setState(() {
                    if (selected) {
                      days.add(day);
                      showError = false;
                    } else {
                      days.remove(day);
                    }
                  });
                },
              );
            }).toList(),
          ),
          if (showError)
            Container(
              padding: EdgeInsets.only(top: 10),
              child: Text(
                'Please select at least one day',
                style: TextStyle(
                  color: Colors.red,
                  fontSize: 14,
                ),
                textAlign: TextAlign.center,
              ),
            ),
        ],
      ),
      actions: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text(
                "Cancel",
                style: TextStyle(
                  color: Colors.red
                ),
              )
            ),
            ElevatedButton(
              onPressed: () async {
                if (days.isEmpty) {
                  setState(() {
                    showError = true;
                  });
                  return;
                }
                
                try {
                  // Convert DaysOfWeek enum to day numbers (0=Sunday, 1=Monday, etc.)
                  final daysOfWeek = days.map((day) => day.index).toList();
                  
                  final timeToUse = scheduleTime ?? widget.defaultTime;
                  
                  
                  Map<String, dynamic> payload;
                  String endpoint;
                  
                  if (widget.isGroupMode) {
                    payload = {
                      'groupId': widget.groupId,
                      'newPos': _blindPosition.toInt(),
                      'time': {
                        'hour': timeToUse.hour,
                        'minute': timeToUse.minute,
                      },
                      'daysOfWeek': daysOfWeek,
                    };
                    
                    if (widget.isEditing) {
                      payload['jobId'] = widget.scheduleId!;
                    }
                    
                    endpoint = widget.isEditing ? 'update_group_schedule' : 'add_group_schedule';
                  } else {
                    payload = {
                      'periphId': widget.peripheralId,
                      'periphNum': widget.peripheralNum,
                      'deviceId': widget.deviceId,
                      'newPos': _blindPosition.toInt(),
                      'time': {
                        'hour': timeToUse.hour,
                        'minute': timeToUse.minute,
                      },
                      'daysOfWeek': daysOfWeek,
                    };
                    
                    if (widget.isEditing) {
                      payload['jobId'] = widget.scheduleId!;
                    }
                    
                    endpoint = widget.isEditing ? 'update_schedule' : 'add_schedule';
                  }
                  final response = await securePost(payload, endpoint);
                  
                  if (response == null) throw Exception("Auth Error");
                  
                  // Handle duplicate schedule (409 Conflict)
                  if (response.statusCode == 409) {
                    if (!context.mounted) return;
                    Navigator.of(context).pop();
                    
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(
                        content: Text(
                          'A schedule already exists at this time for this blind',
                          textAlign: TextAlign.center,
                        ),
                        backgroundColor: Colors.orange,
                        duration: Duration(seconds: 4),
                      )
                    );
                    return;
                  }
                  
                  if (response.statusCode != 201 && response.statusCode != 200) {
                    throw Exception("Server Error");
                  }
                  
                  if (!context.mounted) return;
                  Navigator.of(context).pop();
                  
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(
                        widget.isEditing ? 'Schedule updated successfully' : 'Schedule added successfully',
                        textAlign: TextAlign.center,
                      ),
                      backgroundColor: Colors.green,
                    )
                  );
                } catch (e) {
                  if (!context.mounted) return;
                  ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
                }
              },
              child: Text(widget.isEditing ? "Update" : "Add")
            )
          ]
        )
      ],
    );
  }
}