import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:localstore/localstore.dart';
import 'package:path_provider/path_provider.dart';
import 'package:quiosco_soler_2/memorias_calculo/providers/proyectos_provider.dart';

import '../widgets/encabezado_pais.dart';
import 'package:http/http.dart' as http;

import 'calculadora_ambiental_page.dart';
import 'interfaz_cuadricula_page.dart';

class VentilacionAmbientalPage extends StatefulWidget {
  const VentilacionAmbientalPage({Key? key}) : super(key: key);

  @override
  State<VentilacionAmbientalPage> createState() => _VentilacionAmbientalPageState();
}

class _VentilacionAmbientalPageState extends State<VentilacionAmbientalPage> {
  final ProyectosProvider _proyectosProvider = ProyectosProvider();
  final db = Localstore.instance;
  final List<Map<String, String?>> _projects = [];
  final Map<String, String> _estatusCodigos = {
    "C" : "Cálculo de equipos de extracción y louvers",
    "F" : "Finalizado"
  };

  String _idUsuario = "";
  String _token = "";
  String _pais = "";
  String _code = "";
  bool _isLoading = true;

  double _fontSize = 16.0;

  final ReceivePort _port = ReceivePort();
  List<TaskInfo>? _tasks;
  late String _localPath;

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

    FlutterDownloader.registerCallback(downloadCallback);

    _fetchProjects().then((value){
      if(mounted){
        setState(() => _isLoading = false);
      }
    });
  }

  @override
  void dispose(){
    _unbindBackgroundIsolate();
    super.dispose();
  }

  Future<void> _fetchProjects() async{
    final items = await db.collection('login').get();
    final lastID = items?.keys.last;
    final data = items?[lastID];

    _pais = data['pais'];
    _idUsuario = data['idUsuario'];
    _token = data['token'];

    final paisArr = data['pais'].split(" ");
    _code = paisArr.last.replaceAll("(", "").replaceAll(")", "");

    final proyectos = await _proyectosProvider.fetchProyectos(_idUsuario, "ambiental", _token);
    proyectos.result.forEach((element) {
      final timestamp = int.parse(element.fmodificacion);
      final date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);

      final proyecto = {
        "idProyecto": element.id,
        "nombreProyecto": element.nombre,
        "estatus" : element.estatus,
        "ulModificacion" : date.toString(),
        "datos": element.datos,
        "archpdf": element.archpdf
      };

      _projects.add(proyecto);
    });
  }

  void _bindBackgroundIsolate(){
    bool isSuccess = IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');

    if(!isSuccess){
      _unbindBackgroundIsolate();
      _bindBackgroundIsolate();
      return;
    }

    _port.listen((data) {
      print('UI Isolate Callback: $data');
      String? id = data[0];
      DownloadTaskStatus? status = data [1];
      int? progress = data[2];

      if(_tasks != null && _tasks!.isNotEmpty){
        final task = _tasks!.firstWhere((task) => task.taskId == id);
        setState(() {
          task.status = status;
          task.progress = progress;
        });
      }
    });
  }

  void _unbindBackgroundIsolate() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
  }

  void _requestDownload(TaskInfo task) async{
    task.taskId = await FlutterDownloader.enqueue(
      url: task.link!,
      savedDir: _localPath,
      showNotification: true,
      openFileFromNotification: true,
      saveInPublicStorage: true,
    );
  }

  Future<void> _prepareSaveDir() async {
    _localPath = (await _findLocalPath())!;
    final savedDir = Directory(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
  }

  Future<String?> _findLocalPath() async{
    String externalStorageDirPath;
    if(Platform.isAndroid){
      final directory = await getExternalStorageDirectory();
      externalStorageDirPath = directory!.path;
    }else{
      final directory = await getApplicationDocumentsDirectory();
      externalStorageDirPath = directory.path;
    }

    return externalStorageDirPath;
  }

  static void downloadCallback(String id, DownloadTaskStatus status, int progress){
    print("Task $id: status: $status, progress: $progress");
    final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port')!;
    send.send([id, status, progress]);
  }

  @override
  Widget build(BuildContext context) {
    final _screenSize = MediaQuery.of(context).size;

    if(_screenSize.width <= 360){
      _fontSize = 14.0;
    }else if(_screenSize.width > 360 && _screenSize.width <= 400){
      _fontSize = 16.0;
    }else{
      _fontSize = 18.0;
    }

    return Scaffold(
      body: _isLoading ? const Center(
        child: CircularProgressIndicator(),
      ) : SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              const SizedBox(height: 8.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Row(
                  children: [
                    TextButton(
                      child: Text(
                        "Portal de memorias de cálculo >",
                        style: GoogleFonts.roboto(
                          fontSize: 16.0,
                          fontWeight: FontWeight.bold,
                          fontStyle: FontStyle.italic,
                        ),
                      ),
                      onPressed: () => Navigator.pop(context),
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
                        minimumSize: const Size(0, 0),
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      ),
                    ),
                    const SizedBox(width: 8.0),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
                        child: Text(
                          "Memoria de cálculo de ventilación ambiental",
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: GoogleFonts.roboto(
                            fontSize: 16.0,
                            color: Colors.black54,
                            fontWeight: FontWeight.bold,
                            fontStyle: FontStyle.italic,
                          ),
                        ),
                      ),
                    )
                  ],
                ),
              ),
              const SizedBox(height: 8.0),
              EncabezadoPais(paisCode: _code, paisName: _pais),
              const SizedBox(height: 32.0),
              Image.asset(
                "assets/1.png",
                width: 88.0,
              ),
              const SizedBox(height: 16.0),
              Container(
                width: double.infinity,
                padding: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: const Text(
                  "MEMORIA DE CÁLCULO VENTILACIÓN AMBIENTAL",
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontFamily: "Helvetica Neue Black Cond",
                    fontSize: 28.0,
                  ),
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Text(
                  "NUEVO PROYECTO",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.robotoSlab(
                    fontWeight: FontWeight.bold,
                    fontSize: 18.0,
                  ),
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                width: double.infinity,
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                padding: const EdgeInsets.all(32.0),
                color: const Color(0x0F000000),
                child: Row(
                  children: [
                    Expanded(
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          primary: Colors.white,
                          onPrimary: const Color.fromRGBO(180, 4, 4, 0.25),
                          padding: const EdgeInsets.all(16.0),
                        ),
                        child: Column(
                          children: [
                            Image.asset(
                              "assets/nuevo2.png",
                              width: 64.0,
                            ),
                            const SizedBox(height: 8.0),
                            Text(
                              "Crear nuevo proyecto",
                              style: GoogleFonts.roboto(
                                fontWeight: FontWeight.bold,
                                fontSize: 16.0,
                                color: const Color(0xFFB40404),
                              ),
                            ),
                          ],
                        ),
                        onPressed: () async{
                          final controller = TextEditingController();
                          final shouldCreate = await showDialog(
                            context: context,
                            barrierDismissible: false,
                            builder: (context) => AlertDialog(
                              title: Text(
                                "Nombre del proyecto",
                                textAlign: TextAlign.center,
                                style: GoogleFonts.roboto(
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              content: TextField(
                                controller: controller,
                                decoration: InputDecoration(
                                  hintStyle: GoogleFonts.roboto(
                                    color: Colors.grey,
                                    fontStyle: FontStyle.italic,
                                  ),
                                  hintText: "Ingresa el nombre del proyecto",
                                ),
                                style: GoogleFonts.roboto(),
                                maxLines: 1,
                                maxLength: 100,
                                onSubmitted: (val){
                                  if(val.isNotEmpty){
                                    Navigator.pop(context, true);
                                  }
                                },
                              ),
                              actions: [
                                TextButton(
                                  child: const Text("Cancelar"),
                                  onPressed: () => Navigator.pop(context, false),
                                ),
                                TextButton(
                                  child: const Text("Aceptar"),
                                  onPressed: (){
                                    if(controller.text.isNotEmpty){
                                      Navigator.pop(context, true);
                                    }else{
                                      Fluttertoast.showToast(
                                        msg: "EL nombre del proyecto no debe estar vacío",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 3,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }
                                  },
                                )
                              ],
                            ),
                          );

                          if(shouldCreate){
                            final url = Uri.https("smart.solerpalau.mx", "PR/api/v1/quiosco/matrizMemoriasCalculo/nuevoProyectoVentilacion");
                            final res = await http.post(url,
                              headers: {
                                "Authorization": "Bearer $_token"
                              },
                              body: {
                                "NOMBREPROYECTO": controller.text,
                                "MEMORIA": "ambiental",
                                "FCREACION": DateTime.now().toIso8601String().substring(0, 19),
                                "FMODIF": DateTime.now().toIso8601String().substring(0, 19),
                                "IDUSUARIO": _idUsuario,
                                "ESTATUS": "C",
                              },
                            );

                            final decoded = jsonDecode(res.body);
                            if(!decoded['response']){
                              Fluttertoast.showToast(
                                msg: decoded['message'],
                                toastLength: Toast.LENGTH_SHORT,
                                timeInSecForIosWeb: 3,
                                gravity: ToastGravity.CENTER,
                                webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                              );
                            }else{
                              String idProyecto = decoded['result']['idProyecto'];
                              await Navigator.push(context, MaterialPageRoute(
                                builder: (context) => CalculadoraAmbientalPage(
                                  pais: _pais,
                                  code: _code,
                                  idProyecto: idProyecto,
                                  idUsuario: _idUsuario,
                                  token: _token,
                                  datos: "",
                                  noProyecto: controller.text,
                                  archpdf: "",
                                ),
                              ));

                              setState(() => _isLoading = true);

                              _projects.clear();
                              await _fetchProjects();

                              setState(() => _isLoading = false);
                            }
                          }
                        },
                      ),
                      flex: 1,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(horizontal: 32.0),
                child: Text(
                  "HISTORIAL DE PROYECTOS",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.robotoSlab(
                    fontWeight: FontWeight.bold,
                    fontSize: 18.0,
                  ),
                ),
              ),
              const SizedBox(height: 16.0),
              if(_projects.isEmpty)
                Container(
                  width: double.infinity,
                  margin: const EdgeInsets.symmetric(horizontal: 32.0),
                  child: Text(
                    "Aún no has creado ningún proyecto.",
                    style: GoogleFonts.roboto(
                      fontWeight: FontWeight.bold,
                      fontSize: 18.0,
                    ),
                  ),
                ),
              if(_projects.isNotEmpty)
                Container(
                  height: 256.0,
                  width: double.infinity,
                  margin: const EdgeInsets.symmetric(horizontal: 32.0),
                  child: Column(
                    children: [
                      Container(
                        child: Row(
                          children: [
                            Expanded(
                              child: Text(
                                "Nombre",
                                style: GoogleFonts.roboto(
                                  fontWeight: FontWeight.bold,
                                  fontSize: _fontSize + 2,
                                ),
                              ),
                              flex: 5,
                            ),
                            Expanded(
                              child: Text(
                                "Estatus",
                                style: GoogleFonts.roboto(
                                  fontWeight: FontWeight.bold,
                                  fontSize: _fontSize + 2,
                                ),
                              ),
                              flex: 5,
                            ),
                            Expanded(
                              child: Text(
                                "Última Modificación",
                                style: GoogleFonts.roboto(
                                  fontSize: _fontSize + 2,
                                  fontWeight: FontWeight.bold,
                                ),
                                maxLines: 1,
                                overflow: TextOverflow.ellipsis,
                              ),
                              flex: 3,
                            ),
                            Expanded(
                              child: Container(),
                              flex: 1,
                            ),
                          ],
                        ),
                        padding: const EdgeInsets.only(right: 16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            bottom: BorderSide(
                              color: Colors.black54,
                              width: 2.0,
                            ),
                          ),
                        ),
                      ),
                      Expanded(
                        child: ListView.separated(
                          itemCount: _projects.length,
                          itemBuilder: (context, index){
                            return ListTile(
                              title: Row(
                                children: [
                                  Expanded(
                                    child: Text(
                                      _projects[index]["nombreProyecto"]!,
                                      style: GoogleFonts.roboto(
                                        fontSize: _fontSize,
                                      ),
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                    flex: 5,
                                  ),
                                  Expanded(
                                    child: Text(
                                      _estatusCodigos[_projects[index]["estatus"]!]!,
                                      style: GoogleFonts.roboto(
                                        fontSize: _fontSize,
                                      ),
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                    flex: 5,
                                  ),
                                  Expanded(
                                    child: Text(
                                      _buildDate(_projects[index]["ulModificacion"]!),
                                      style: GoogleFonts.roboto(
                                        fontSize: _fontSize,
                                      ),
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                    flex: 3,
                                  ),
                                  Expanded(
                                    child: PopupMenuButton<String>(
                                      onSelected: (val) async{
                                        const auth = "smart.solerpalau.mx";
                                        if(val == "Eliminar"){
                                          final url = Uri.https(auth, "PR/api/v1/quiosco/matrizMemoriasCalculo/borrarProyectos");
                                          final res = await http.post(url,
                                            headers: {
                                              "Authorization": "Bearer $_token",
                                            },
                                            body: {
                                              "IDUSUARIO": _idUsuario,
                                              "IDPROYECTO": _projects[index]["idProyecto"],
                                            },
                                          );

                                          final decoded = jsonDecode(res.body);

                                          if(!decoded['response']){
                                            Fluttertoast.showToast(
                                              msg: decoded['message'],
                                              toastLength: Toast.LENGTH_SHORT,
                                              timeInSecForIosWeb: 4,
                                              gravity: ToastGravity.CENTER,
                                              webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                            );
                                          }else{
                                            Fluttertoast.showToast(
                                              msg: decoded['message'],
                                              toastLength: Toast.LENGTH_SHORT,
                                              timeInSecForIosWeb: 4,
                                              gravity: ToastGravity.CENTER,
                                              webBgColor: "linear-gradient(to right, #266B1F, #98F58F)",
                                            );

                                            setState(() => _isLoading = true);

                                            _projects.clear();
                                            await _fetchProjects();

                                            setState(() => _isLoading = false);
                                          }
                                        }else if(val == "Descargar PDF"){
                                          Fluttertoast.showToast(
                                            msg: "Descargando archivo...",
                                            toastLength: Toast.LENGTH_SHORT,
                                          );

                                          final task = TaskInfo(name: _projects[index]["nombreProyecto"]!, link: _projects[index]["archpdf"]!);
                                          _requestDownload(task);
                                        }
                                      },
                                      itemBuilder: (context) => ["Eliminar", if(_projects[index]["archpdf"]!.isNotEmpty)"Descargar PDF"].map((e) => PopupMenuItem(
                                        value: e,
                                        child: Row(
                                          children: [
                                            Text(
                                              e,
                                              style: GoogleFonts.roboto(
                                                fontSize: 16.0,
                                                color: Colors.black54,
                                              ),
                                            ),
                                            const SizedBox(width: 8.0),
                                            Icon(
                                              e == "Eliminar" ? Icons.delete : Icons.file_download,
                                              color: Colors.black54,
                                            )
                                          ],
                                        ),
                                      )).toList(),
                                    ),
                                    flex: 1,
                                  ),
                                ],
                              ),
                              onTap: () async{
                                await Navigator.push(context, MaterialPageRoute(
                                  builder: (context) => CalculadoraAmbientalPage(
                                    pais: _pais,
                                    code: _code,
                                    idProyecto: _projects[index]['idProyecto']!,
                                    idUsuario: _idUsuario,
                                    token: _token,
                                    datos: _projects[index]['datos']!,
                                    noProyecto: _projects[index]['nombreProyecto']!,
                                    archpdf: "",
                                  ),
                                ));

                                setState(() => _isLoading = true);

                                _projects.clear();
                                await _fetchProjects();

                                setState(() => _isLoading = false);
                              },
                              contentPadding: EdgeInsets.zero,
                            );
                          },
                          separatorBuilder: (context, index){
                            return const Divider();
                          },
                        ),
                      )
                    ],
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }

  String _buildDate(String date){
    final parsed = DateTime.parse(date);
    final now = DateTime.now();

    final diff = now.difference(parsed).inDays;
    if(diff == 0){
      return "Hoy";
    }else if(diff == 1){
      return "Ayer";
    }else if(diff >= 2 && diff < 31){
      return "Hace $diff días";
    }else if(diff >= 31 && diff <= 359){
      final diffMes = diff~/30;
      return "Hace $diffMes mes(es)";
    }else if(diff > 359){
      final diffAnio = diff~/359;
      return "Hace $diffAnio año(s)";
    }else{
      return "Hace mucho tiempo";
    }
  }
}
