import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:image_picker/image_picker.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/photo_view_web.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/screens/city.dart';
import 'package:prosappco/src/screens/new_number.dart';
import 'package:prosappco/src/screens/new_password.dart';
import 'package:universal_html/html.dart' as html;

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

  @override
  State<ProfileWebScreen> createState() => _ProfileWebScreenState();
}

class _ProfileWebScreenState extends State<ProfileWebScreen> {
  final uid = AuthenticationRepository.instance.getCurrentUserUid();
  final FirebaseStorage storage = FirebaseStorage.instance;
  late final FirebaseAuth _auth;
  List<City>? filteredCities;

  // variables imagen
  String selectedImage = '';
  XFile? file;
  Uint8List? selectedImagInBytes;
  String photoTemp = '';

  // controladores
  final _formKey = GlobalKey<FormState>();
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _phoneNumberController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool _obscureText = true;

  // variables
  String _ciudad = '...';
  String _photo = '...';
  String? _email = '';

  @override
  void initState() {
    super.initState();

    final uid = AuthenticationRepository.instance.getCurrentUserUid();
    _auth = FirebaseAuth.instance;

    final currentUser = _auth.currentUser;

    if (currentUser != null && currentUser.phoneNumber != null) {
      _phoneNumberController.text = currentUser.phoneNumber!;
    }

    if (currentUser != null && currentUser.displayName != null) {
      _nameController.text = currentUser.displayName!;
    }
    if (currentUser != null && currentUser.email != null) {
      _emailController.text = currentUser.email!;
    }

    _email = currentUser?.email;

    if (_ciudad == '...') {
      AuthenticationRepository.instance
          .getCity(uid.toString())
          .then((String s) => setState(() {
                _ciudad = s;
              }));
    }

    if (_photo == '...') {
      AuthenticationRepository.instance
          .getPhoto(uid.toString())
          .then((String s) => setState(() {
                _photo = s;
              }));
    }
  }

  _selectFile(bool imageFrom) async {
    FilePickerResult? fileResult = await FilePicker.platform.pickFiles();

    if (fileResult != null) {
      setState(() {
        selectedImage = fileResult.files.first.name;
        selectedImagInBytes = fileResult.files.first.bytes;
      });
    }
  }

  _uploadFile() async {
    try {
      final now = DateTime.now();
      final formattedDate = DateFormat('HHmmssddMMyyyy').format(now);
      final milliseconds = (now.microsecondsSinceEpoch / 1000).round();
      final random = '$formattedDate$milliseconds';

      final Reference ref = FirebaseStorage.instance
          .ref()
          .child('users')
          .child(uid!)
          .child('profile')
          .child(random);

      final metaData = SettableMetadata(contentType: 'image/jpeg');

      final UploadTask uploadTask = ref.putData(selectedImagInBytes!, metaData);

      final TaskSnapshot snapshot = await uploadTask.whenComplete(() => true);

      photoTemp = ref.fullPath;

      if (snapshot.state == TaskState.success) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      print('web image error - $e');
    }
  }

  Future<void> updateInfo() async {
    final currentUser = _auth.currentUser;
    final currentPhoneNumber = _auth.currentUser!.phoneNumber;

    String newName = _nameController.text.trim();
    String newEmail = _emailController.text.trim();
    String newPassword = _passwordController.text.trim();

    if (newName.isEmpty) {
      // Si el nuevo nombre está vacío, no lo actualizamos y mostramos un mensaje al usuario
      Get.snackbar(
        'Nombre Invalido',
        'Ingrese un nombre válido.',
        snackPosition: SnackPosition.BOTTOM,
      );
      return;
    } else {
      try {
        await FirebaseAuth.instance.currentUser!.updateDisplayName(newName);
        await FirebaseFirestore.instance.collection('users').doc(uid).update({
          'name': newName,
          'lowerName': newName.toLowerCase(),
        });
      } catch (e) {
        print('Error al actualizar el nombre: $e');
      }
    }
    if (newEmail.isEmpty) {
      // Si el nuevo nombre está vacío, no lo actualizamos y mostramos un mensaje al usuario
      Get.snackbar(
        'Correo Invalido',
        'Ingrese un email válido.',
        snackPosition: SnackPosition.BOTTOM,
      );
      return;
    }

    try {
      await FirebaseAuth.instance.currentUser!.updateDisplayName(newName);
      await FirebaseFirestore.instance.collection('users').doc(uid).update({
        'name': newName,
        'lowerName': newName.toLowerCase(),
      });
    } catch (e) {
      print('Error al actualizar el nombre: $e');
    }

    if (currentUser?.email != newEmail) {
      if (newPassword.isNotEmpty) {
        await FirebaseFirestore.instance.collection('users').doc(uid).update({
          'email': newEmail,
        });
        updateEmailAndPassword(newEmail, newPassword);
      } else {
        Get.snackbar(
          'Contraseña Invalida',
          'Porfavor ingrese una contraseña.',
          snackPosition: SnackPosition.BOTTOM,
        );
      }
    }

    String? selectedCity = _ciudad;

    // Guardar la ciudad seleccionada en el documento del usuario
    try {
      await FirebaseFirestore.instance.collection('users').doc(uid).update({
        'city': selectedCity,
      });
    } catch (e) {
      print('Error al actualizar la ciudad: $e');
    }

    try {
      await FirebaseFirestore.instance
          .collection('users')
          .doc(uid)
          .update({'phoneNumber': currentPhoneNumber});
    } catch (e) {
      print('e');
    }

    try {
      await FirebaseFirestore.instance
          .collection('users')
          .doc(uid)
          .update({'email': newEmail});
    } catch (e) {
      print('e');
    }

    try {
      if (selectedImagInBytes == null) {
        return;
      } else {
        await _uploadFile();
        updateImage(photoTemp);
      }
    } catch (e) {
      print('Error al actualizar la imagen de perfil $e');
    }
  }

  Future<void> updateImage(image) async {
    try {
      await FirebaseFirestore.instance
          .collection('users')
          .doc(uid)
          .update({'photo': image});
    } catch (e) {
      try {
        await FirebaseFirestore.instance
            .collection('users')
            .doc(uid)
            .set({'photo': image});
      } catch (e) {
        print('Error al agregar la imagen de perfil: $e');
      }

      print('Error al actualizar la imagen de perfil: $e');
    }
  }

  Future<void> updateEmailAndPassword(String email, String password) async {
    final User? user = FirebaseAuth.instance.currentUser;
    if (user != null) {
      try {
        await user.updateEmail(email);
        await user.updatePassword(password);
      } catch (e) {
        Get.snackbar(
          'Agregar correo',
          'Inicie sesión para asegurarnos de que seas tú .',
          snackPosition: SnackPosition.BOTTOM,
        );
        AuthenticationRepository.instance.logout(uid!);
      }
    }
  }

  Future<List<City>> _getCities() async {
    List<City> citys = [];
    try {
      QuerySnapshot countries = await countriesCollection.get();
      for (DocumentSnapshot country in countries.docs) {
        String countryName = country.id;
        Map<String, dynamic> data = country.data() as Map<String, dynamic>;
        Map<String, Map<String, String>> states = {};

        for (var entry in data.entries) {
          String key = entry.key;
          Map<String, String> cityData = Map<String, String>.from(entry.value);
          states[key] = cityData;
        }

        for (var state in states.entries) {
          var citysState = state.value.entries.map((city) => City(
                cityName: city.key,
                coordsOfCity: city.value,
                stateOfCity: state.key,
                countryOfCity: countryName,
              ));

          citys.addAll(citysState);
        }
      }
    } catch (e) {
      print('Error obteniendo las ciudades: $e');
    }
    return citys;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFD6F4FF),
      appBar: PopAppbar(
          onPressed: () {
            Navigator.pop(context);
          },
          label: 'Perfil'),
      body: Center(
        child: SizedBox(
          width: 300,
          height: 600,
          child: Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
            ),
            color: Colors.white,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20.0),
              child: Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      padding: const EdgeInsets.only(top: 20, bottom: 20),
                      child: (selectedImagInBytes != null)
                          ? LocalPhotoWeb(file: selectedImagInBytes)
                          : ReferencePhotoWeb(ref: storage.ref().child(_photo)),
                    ),
                    TextFormField(
                      controller: _nameController,
                      maxLength: 50,
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Porfavor ingrese un nombre.';
                        }
                        if (value.length < 5) {
                          return 'Debe tener al menos 5 caracteres.';
                        }
                        return null;
                      },
                      decoration: const InputDecoration(
                        prefixIcon: Icon(Icons.person_outline),
                        hintText: 'Nombre (Obligatorio)',
                      ),
                    ),
                    _email != null
                        ? TextFormField(
                            onTap: () {
                              Navigator.push(context, CupertinoPageRoute(
                                builder: (BuildContext context) {
                                  return NewPasswordScreen();
                                },
                              ));
                            },
                            readOnly: true,
                            controller: _emailController,
                            decoration: const InputDecoration(
                              prefixIcon: Icon(Icons.email_outlined),
                              hintText: 'Email (Obligatorio)',
                            ),
                          )
                        : TextFormField(
                            controller: _emailController,
                            validator: (String? value) {
                              if (value == null || value.isEmpty) {
                                return 'Por favor ingrese un email';
                              }
                              final RegExp emailRegExp =
                                  RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
                              if (!emailRegExp.hasMatch(value)) {
                                return 'Por favor ingrese un email válido';
                              }
                              return null;
                            },
                            decoration: const InputDecoration(
                              prefixIcon: Icon(Icons.email_outlined),
                              hintText: 'Email (Obligatorio)',
                            ),
                          ),
                    const SizedBox(height: 20.0),
                    _email != null
                        ? const SizedBox.shrink()
                        : TextFormField(
                            controller: _passwordController,
                            obscureText: _obscureText,
                            validator: (value) {
                              if (value == null || value.isEmpty) {
                                return 'Porfavor ingrese una contraseña.';
                              }
                              if (value.length < 5) {
                                return 'Debe tener al menos 5 caracteres.';
                              }
                              return null;
                            },
                            decoration: InputDecoration(
                              prefixIcon: const Icon(Icons.lock_outline),
                              suffixIcon: IconButton(
                                icon: Icon(
                                  _obscureText
                                      ? Icons.visibility
                                      : Icons.visibility_off,
                                  color: Colors.grey,
                                ),
                                onPressed: () {
                                  setState(() {
                                    _obscureText = !_obscureText;
                                  });
                                },
                              ),
                              hintText: 'Contraseña (Obligatorio)',
                            ),
                          ),
                    _email != null
                        ? const SizedBox.shrink()
                        : const SizedBox(height: 20.0),
                    FutureBuilder<List<City>>(
                      future: _getCities(),
                      builder: (context, snapshot) {
                        if (snapshot.connectionState ==
                            ConnectionState.waiting) {
                          return const Center(
                            child: CircularProgressIndicator(),
                          );
                        } else if (snapshot.hasError) {
                          return const Center(
                            child: Text('Error al obtener las ciudades'),
                          );
                        } else {
                          List<City> filteredCities = snapshot.data!;

                          return DropdownButtonFormField<String>(
                            value: _ciudad,
                            onChanged: (String? newValue) {
                              setState(() {
                                _ciudad = newValue!;
                              });
                            },
                            items: filteredCities.map((City city) {
                              return DropdownMenuItem<String>(
                                value: city.cityName,
                                child: Text(city.cityName ?? ''),
                              );
                            }).toList(),
                            decoration: InputDecoration(
                              prefixIcon: const Icon(Icons.near_me),
                              hintText: _ciudad,
                            ),
                          );
                        }
                      },
                    ),
                    const SizedBox(height: 20.0),
                    TextFormField(
                      controller: _phoneNumberController,
                      readOnly: true,
                      onTap: () {
                        Navigator.of(context).push(
                          CupertinoPageRoute(
                            builder: (BuildContext context) {
                              return const NewNumberScreen();
                            },
                          ),
                        );
                      },
                      decoration: const InputDecoration(
                          prefixIcon: Icon(Icons.phone_android),
                          suffixIcon: Icon(Icons.edit_outlined),
                          hintText: '+57'),
                    ),
                    Container(
                      alignment: Alignment.bottomCenter,
                      margin: const EdgeInsets.only(top: 30),
                      padding: const EdgeInsets.only(bottom: 30),
                      child: ElevatedButton(
                        onPressed: () async {
                          if (_formKey.currentState!.validate()) {
                            await updateInfo().whenComplete(() {
                              html.window.location.reload();

                              Get.snackbar(
                                'Perfil',
                                'Información actualizada correctamente.',
                                snackPosition: SnackPosition.TOP,
                              );
                            });
                          }
                        },
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF2BA4EC),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(50),
                          ),
                          elevation: 0,
                          minimumSize: const Size(200, 50),
                        ),
                        child: const Text(
                          'Guardar',
                          style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: 17,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
