import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/cupertino.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geocoding/geocoding.dart';

import '../../Models/ordersModels/commonResponse.dart';
import '../../Notifiers/hrmProvider/attendanceListProvider.dart';
import '../../Utils/app_colors.dart';
import '../../Utils/commonServices.dart';
import '../../Utils/commonWidgets.dart';
import '../../Utils/custom_snackbar.dart';
import '../../Utils/dropdownTheme.dart';

class AddManualAttendanceScreen extends StatefulWidget {
  const AddManualAttendanceScreen({super.key});

  @override
  State<AddManualAttendanceScreen> createState() =>
      _AddManualAttendanceScreenState();
}

class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
  Dropdowntheme ddtheme = Dropdowntheme();
  final ImagePicker picker = ImagePicker();

  // Connectivity
  Map _source = {ConnectivityResult.mobile: true};
  final MyConnectivity _connectivity = MyConnectivity.instance;
  String connection = "Online";

  // Controllers
  final checkInTime = TextEditingController();
  final checkInLocation = TextEditingController();
  final checkInDescription = TextEditingController();
  XFile? checkInProof;

  final checkOutTime = TextEditingController();
  final checkOutLocation = TextEditingController();
  final checkOutDescription = TextEditingController();
  XFile? checkOutProof;

  String? selectedType;
  final List<String> types = ["Check In", "Check Out", "Check In/Out"];

  // Errors
  String? dateError, typeError;
  String? checkInTimeError,
      checkInLocError,
      checkInDescError,
      checkInProofError;
  String? checkOutTimeError,
      checkOutLocError,
      checkOutDescError,
      checkOutProofError;

  // In your Attendancelistprovider class
  CommonResponse? get addResponse => addResponse;
  String? get errorMessage => errorMessage;

  @override
  void initState() {
    super.initState();
    _connectivity.initialise();
    _connectivity.myStream.listen((src) {
      setState(() => _source = src);
    });

    WidgetsBinding.instance.addPostFrameCallback((_) {
      _fetchInitialLocation();
    });

    // Add listeners to text controllers to clear errors when user types
    checkInLocation.addListener(_clearCheckInLocError);
    checkInDescription.addListener(_clearCheckInDescError);
    checkOutLocation.addListener(_clearCheckOutLocError);
    checkOutDescription.addListener(_clearCheckOutDescError);
  }

  @override
  void dispose() {
    _connectivity.disposeStream();
    checkInLocation.removeListener(_clearCheckInLocError);
    checkInDescription.removeListener(_clearCheckInDescError);
    checkOutLocation.removeListener(_clearCheckOutLocError);
    checkOutDescription.removeListener(_clearCheckOutDescError);
    super.dispose();
  }

  // Error clearing methods
  void _clearCheckInLocError() {
    if (checkInLocError != null && checkInLocation.text.isNotEmpty) {
      setState(() => checkInLocError = null);
    }
  }

  void _clearCheckInDescError() {
    if (checkInDescError != null && checkInDescription.text.isNotEmpty) {
      setState(() => checkInDescError = null);
    }
  }

  void _clearCheckOutLocError() {
    if (checkOutLocError != null && checkOutLocation.text.isNotEmpty) {
      setState(() => checkOutLocError = null);
    }
  }

  void _clearCheckOutDescError() {
    if (checkOutDescError != null && checkOutDescription.text.isNotEmpty) {
      setState(() => checkOutDescError = null);
    }
  }

  Future<void> _fetchInitialLocation() async {
    String loc = await getCurrentLocation();
    setState(() {
      checkInLocation.text = loc;
      checkOutLocation.text = loc;
    });
  }

  Future<String> getCurrentLocation() async {
    try {
      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) return "Permission denied";
      }
      if (permission == LocationPermission.deniedForever) {
        return "Permission permanently denied";
      }

      Position pos = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
      );

      List<Placemark> placemarks = await placemarkFromCoordinates(
        pos.latitude,
        pos.longitude,
      );

      if (placemarks.isNotEmpty) {
        Placemark p = placemarks.first;
        return "${p.locality}, ${p.administrativeArea}, ${p.country}";
      }
      return "${pos.latitude}, ${pos.longitude}";
    } catch (e) {
      return "Error: $e";
    }
  }

  Future<void> _pickTime(
    TextEditingController controller,
    bool isCheckIn,
  ) async {
    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );
    if (picked != null) {
      controller.text = picked.format(context);
      // Clear error when time is selected
      if (isCheckIn) {
        if (checkInTimeError != null) setState(() => checkInTimeError = null);
      } else {
        if (checkOutTimeError != null) setState(() => checkOutTimeError = null);
      }
    }
  }

  Future<void> _pickFile(bool isCheckIn) async {
    showModalBottomSheet(
      useSafeArea: true,
      isDismissible: true,
      showDragHandle: true,
      backgroundColor: Colors.white,
      context: context,
      builder: (_) {
        return SafeArea(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ListTile(
                leading: const Icon(Icons.camera_alt),
                title: const Text("Capture photo from camera"),
                onTap: () async {
                  final XFile? file = await picker.pickImage(
                    source: ImageSource.camera,
                  );
                  if (file != null) {
                    setState(() {
                      if (isCheckIn) {
                        checkInProof = file;
                        if (checkInProofError != null)
                          setState(() => checkInProofError = null);
                      } else {
                        checkOutProof = file;
                        if (checkOutProofError != null)
                          setState(() => checkOutProofError = null);
                      }
                    });
                  }
                  Navigator.pop(context);
                },
              ),
              ListTile(
                leading: const Icon(Icons.photo_library),
                title: const Text("Select photo from gallery"),
                onTap: () async {
                  final XFile? file = await picker.pickImage(
                    source: ImageSource.gallery,
                  );
                  if (file != null) {
                    setState(() {
                      if (isCheckIn) {
                        checkInProof = file;
                        if (checkInProofError != null)
                          setState(() => checkInProofError = null);
                      } else {
                        checkOutProof = file;
                        if (checkOutProofError != null)
                          setState(() => checkOutProofError = null);
                      }
                    });
                  }
                  Navigator.pop(context);
                },
              ),
            ],
          ),
        );
      },
    );
  }

  void _submitForm(BuildContext context) async {
    // Reset errors first
    dateError = null;
    typeError = null;
    checkInTimeError =
        checkInLocError = checkInDescError = checkInProofError = null;
    checkOutTimeError =
        checkOutLocError = checkOutDescError = checkOutProofError = null;

    final provider = Provider.of<Attendancelistprovider>(
      context,
      listen: false,
    );

    // --- Date Validation (allow today, yesterday, day before yesterday) ---
    if (provider.dateController.text.isEmpty) {
      dateError = "Please select a date";
    } else {
      try {
        final enteredDate = DateFormat(
          "dd MMM yyyy",
        ).parse(provider.dateController.text);
        provider.setSelectedDate(enteredDate);

        final today = DateTime.now();
        final yesterday = today.subtract(const Duration(days: 1));
        final dayBeforeYesterday = today.subtract(const Duration(days: 2));

        // Normalize dates (ignore time part)
        bool isValid =
            enteredDate.year == today.year &&
            enteredDate.month == today.month &&
            (enteredDate.day == today.day ||
                enteredDate.day == yesterday.day ||
                enteredDate.day == dayBeforeYesterday.day);

        if (!isValid) {
          dateError =
              "Date must be today, yesterday, or the day before yesterday";
        }
      } catch (e) {
        dateError = "Invalid date format (use dd MMM yyyy)";
      }
    }

    // --- Type Validation ---
    if (selectedType == null) {
      typeError = "Please select type";
    }

    // --- Check In Validations ---
    if (selectedType == "Check In" || selectedType == "Check In/Out") {
      if (checkInTime.text.isEmpty)
        checkInTimeError = "Please select check-in time";
      if (checkInLocation.text.isEmpty)
        checkInLocError = "Please enter check-in location";
      if (checkInDescription.text.isEmpty)
        checkInDescError = "Please enter description";
      if (checkInProof == null)
        checkInProofError = "Please attach check-in proof";
    }

    // --- Check Out Validations ---
    if (selectedType == "Check Out" || selectedType == "Check In/Out") {
      if (checkOutTime.text.isEmpty)
        checkOutTimeError = "Please select check-out time";
      if (checkOutLocation.text.isEmpty)
        checkOutLocError = "Please enter check-out location";
      if (checkOutDescription.text.isEmpty)
        checkOutDescError = "Please enter description";
      if (checkOutProof == null)
        checkOutProofError = "Please attach check-out proof";
    }

    // --- Stop if any error ---
    if ([
      dateError,
      typeError,
      checkInTimeError,
      checkInLocError,
      checkInDescError,
      checkInProofError,
      checkOutTimeError,
      checkOutLocError,
      checkOutDescError,
      checkOutProofError,
    ].any((e) => e != null)) {
      setState(() {}); // refresh UI to show error messages
      return;
    }

    // --- Format date for server ---
    String formattedDate = "";
    try {
      final parsedDate = DateFormat(
        "dd MMM yyyy",
      ).parse(provider.dateController.text);
      formattedDate = DateFormat("yyyy-MM-dd").format(parsedDate);
    } catch (e) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text("Error formatting date: $e")));
      return;
    }

    // --- Build data according to type ---
    String? finalCheckInTime;
    String? finalCheckInLoc;
    File? finalCheckInProof;
    String? finalCheckOutTime;
    String? finalCheckOutLoc;
    File? finalCheckOutProof;
    String? finalNote;

    if (selectedType == "Check In") {
      finalCheckInTime = checkInTime.text;
      finalCheckInLoc = checkInLocation.text;
      finalCheckInProof = File(checkInProof!.path);
      finalNote = checkInDescription.text;
    } else if (selectedType == "Check Out") {
      finalCheckOutTime = checkOutTime.text;
      finalCheckOutLoc = checkOutLocation.text;
      finalCheckOutProof = File(checkOutProof!.path);
      finalNote = checkOutDescription.text;
    } else if (selectedType == "Check In/Out") {
      finalCheckInTime = checkInTime.text;
      finalCheckInLoc = checkInLocation.text;
      finalCheckInProof = File(checkInProof!.path);
      finalCheckOutTime = checkOutTime.text;
      finalCheckOutLoc = checkOutLocation.text;
      finalCheckOutProof = File(checkOutProof!.path);
      finalNote = "${checkInDescription.text} / ${checkOutDescription.text}";
    }

    // --- Submit to provider ---
    await provider.addAttendanceRequest(
      context,
      process: "Manual",
      type: selectedType!,
      loc:
          selectedType == "Check In"
              ? checkInLocation.text
              : selectedType == "Check Out"
              ? checkOutLocation.text
              : "${checkInLocation.text}, ${checkOutLocation.text}",
      checkDate: formattedDate,
      checkInTime: finalCheckInTime,
      checkInLoc: finalCheckInLoc,
      checkInProof: finalCheckInProof,
      checkOutTime: finalCheckOutTime,
      checkOutLoc: finalCheckOutLoc,
      checkOutProof: finalCheckOutProof,
      note: finalNote,
    );

    // --- Response handling ---
    if (provider.addResponse != null && provider.addResponse!.error == "0") {
      CustomSnackBar.showSuccess(
        context: context,
        message: provider.addResponse!.message ??
            "Attendance Submitted Successfully",
      );

      // Reset fields
      setState(() {
        selectedType = null;
        provider.dateController.clear();
        checkInTime.clear();
        checkInLocation.clear();
        checkInDescription.clear();
        checkInProof = null;
        checkOutTime.clear();
        checkOutLocation.clear();
        checkOutDescription.clear();
        checkOutProof = null;
      });

      _fetchInitialLocation();
    } else {
      String errorMessage =
          provider.errorMessage ?? "Failed to submit attendance";
      if (errorMessage.contains("Check In is not Available")) {
        errorMessage =
            "Cannot submit Check Out without a Check In record for this date";
      }
      if (errorMessage.contains("2")) {
        errorMessage = "Only One manual Request can be added in a month !";
      }

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(errorMessage), backgroundColor: Colors.red),
      );
    }
  }

  Future<bool> _onBackPressed(BuildContext context) async {
    Navigator.pop(context, true);
    return true;
  }

  @override
  Widget build(BuildContext context) {
    switch (_source.keys.toList()[0]) {
      case ConnectivityResult.mobile:
      case ConnectivityResult.wifi:
        connection = 'Online';
        break;
      default:
        connection = 'Offline';
    }

    return (connection == "Online")
        ? Platform.isAndroid
            ? WillPopScope(
              onWillPop: () => _onBackPressed(context),
              child: SafeArea(
                top: false,
                bottom: true,
                child: _scaffold(context),
              ),
            )
            : _scaffold(context)
        : NoNetwork(context);
  }

  Widget _scaffold(BuildContext context) {
    return Consumer<Attendancelistprovider>(
      builder: (context, provider, child) {
        return Scaffold(
          backgroundColor: Colors.white,
          appBar: appbar2New(
            context,
            "Add Manual Attendance",
            () {},
            SizedBox.shrink(),
            0xFFFFFFFF,
          ),
          body: Scrollbar(
            child: SingleChildScrollView(
              padding: const EdgeInsets.all(12),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Date field with error clearing
                  GestureDetector(
                    onTap: () {
                      provider.showDatePickerDialog(context);
                      if (dateError != null) {
                        setState(() => dateError = null);
                      }
                    },
                    child: AbsorbPointer(
                      child: textControllerWidget(
                        context,
                        provider.dateController,
                        "Date",
                        "Select Date",
                        (v) {},
                        TextInputType.text,
                        false,
                        null,
                        null,
                        null,
                        TextInputAction.next,
                      ),
                    ),
                  ),
                  errorWidget(context, dateError),

                  // Type dropdown with error clearing
                  TextWidget(context, "Type"),
                  DropdownButtonHideUnderline(
                    child: Row(
                      children: [
                        Expanded(
                          child: DropdownButton2<String>(
                            isExpanded: true,
                            hint: const Text("Select Type"),
                            items:
                                types
                                    .map(
                                      (e) => DropdownMenuItem(
                                        value: e,
                                        child: Text(e),
                                      ),
                                    )
                                    .toList(),
                            value: selectedType,
                            onChanged: (val) {
                              setState(() {
                                selectedType = val;
                                if (typeError != null) {
                                  typeError = null;
                                }
                              });
                            },
                            buttonStyleData: ddtheme.buttonStyleData,
                            iconStyleData: ddtheme.iconStyleData,
                            menuItemStyleData: ddtheme.menuItemStyleData,
                            dropdownStyleData: ddtheme.dropdownStyleData,
                          ),
                        ),
                      ],
                    ),
                  ),
                  errorWidget(context, typeError),

                  if (selectedType == "Check In" ||
                      selectedType == "Check In/Out")
                    _buildSection("Check In"),
                  if (selectedType == "Check Out" ||
                      selectedType == "Check In/Out")
                    _buildSection("Check Out"),

                  SizedBox(height: 80),
                ],
              ),
            ),
          ),
          bottomNavigationBar: InkResponse(
            onTap: provider.isSubmitting ? null : () => _submitForm(context),
            child: Container(
              height: 45,
              alignment: Alignment.center,
              margin: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: AppColors.app_blue,
                borderRadius: BorderRadius.circular(15),
              ),
              child:
                  provider.isSubmitting
                      ? CircularProgressIndicator.adaptive(
                        valueColor: AlwaysStoppedAnimation(AppColors.white),
                      )
                      : const Text(
                        "Submit",
                        style: TextStyle(
                          fontSize: 15,
                          fontFamily: "JakartaMedium",
                          color: Colors.white,
                        ),
                      ),
            ),
          ),
        );
      },
    );
  }

  Widget _buildSection(String title) {
    final isCheckIn = title == "Check In";
    final timeCtrl = isCheckIn ? checkInTime : checkOutTime;
    final locCtrl = isCheckIn ? checkInLocation : checkOutLocation;
    final descCtrl = isCheckIn ? checkInDescription : checkOutDescription;
    final proofFile = isCheckIn ? checkInProof : checkOutProof;
    final proofError = isCheckIn ? checkInProofError : checkOutProofError;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Time field with error clearing
        GestureDetector(
          onTap: () => _pickTime(timeCtrl, isCheckIn),
          child: AbsorbPointer(
            child: textControllerWidget(
              context,
              timeCtrl,
              "$title Time",
              "Select Time",
              (v) {},
              TextInputType.text,
              false,
              null,
              null,
              null,
              TextInputAction.next,
            ),
          ),
        ),
        errorWidget(context, isCheckIn ? checkInTimeError : checkOutTimeError),

        // Location field (errors cleared via listener)
        textControllerWidget(
          context,
          locCtrl,
          "$title Location",
          "Enter Location",
          (v) {},
          TextInputType.text,
          false,
          null,
          null,
          null,
          TextInputAction.next,
        ),
        errorWidget(context, isCheckIn ? checkInLocError : checkOutLocError),

        // Description field (errors cleared via listener)
        textControllerWidget(
          context,
          descCtrl,
          "$title Description",
          "Enter Description",
          (v) {},
          TextInputType.text,
          false,
          null,
          null,
          null,
          TextInputAction.done,
        ),
        errorWidget(context, isCheckIn ? checkInDescError : checkOutDescError),

        // Proof attachment with error clearing
        InkResponse(
          onTap: () => _pickFile(isCheckIn),
          child: Container(
            margin: const EdgeInsets.symmetric(vertical: 10),
            height: 45,
            width: double.infinity,
            decoration: BoxDecoration(
              color: const Color(0xFFE6F6FF),
              borderRadius: BorderRadius.circular(12),
              border: Border.all(color: AppColors.app_blue, width: 0.5),
            ),
            child: Center(
              child: Text(
                "Attach $title Proof",
                style: TextStyle(
                  fontFamily: "JakartaMedium",
                  color: AppColors.app_blue,
                ),
              ),
            ),
          ),
        ),
        if (proofFile != null)
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Text(
                  proofFile.name,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(fontSize: 12),
                ),
              ),
              IconButton(
                icon: const Icon(Icons.close, color: Colors.red, size: 18),
                onPressed: () {
                  setState(() {
                    if (isCheckIn) {
                      checkInProof = null;
                    } else {
                      checkOutProof = null;
                    }
                  });
                },
              ),
            ],
          ),
        errorWidget(context, proofError),
      ],
    );
  }
}

// Helper widget to display errors
Widget errorWidget(BuildContext context, String? error) {
  if (error == null) return const SizedBox(height: 8);

  return Padding(
    padding: const EdgeInsets.only(bottom: 8, left: 4),
    child: Text(error, style: const TextStyle(color: Colors.red, fontSize: 12)),
  );
}
