import 'dart:async';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:easy_app_installer/easy_app_installer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_svg/svg.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:unit2/screens/unit2/login/components/showAlert.dart';
import 'package:unit2/theme-data.dart/btn-style.dart';

import '../../../../bloc/user/user_bloc.dart';
import '../../../../theme-data.dart/colors.dart';
import '../../../../utils/cpu_architecture.dart';
import '../../../../utils/text_container.dart';
import '../../../../widgets/wave.dart';

class Update extends StatefulWidget {
  final String apkVersion;
  final String currenVersion;
  const Update(
      {super.key, required this.apkVersion, required this.currenVersion});

  @override
  State<Update> createState() => _UpdateState();
}

class _UpdateState extends State<Update> {
  String progressRating = '0';
  bool downloading = false;
  bool isDownloaded = false;
  bool asyncCall = false;
  Dio dio = Dio();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Stack(children: [
        BlocBuilder<UserBloc, UserState>(
          builder: (context, state) {
            if (state is VersionLoaded) {
              return ProgressHUD(
                child: SingleChildScrollView(
                  child: Container(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 40, vertical: 25),
                    height: MediaQuery.of(context).size.height,
                    alignment: Alignment.center,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            SvgPicture.asset(
                              'assets/svgs/download.svg',
                              height: 200.0,
                              width: 200.0,
                              allowDrawingOutsideViewBox: true,
                            ),
                            const SizedBox(
                              height: 5,
                            ),
                            Text("UPDATE REQUIRED!",
                                textAlign: TextAlign.center,
                                style: Theme.of(context)
                                    .textTheme
                                    .displaySmall!
                                    .copyWith(color: primary, fontSize: 28)),
                          ],
                        ),
                        const SizedBox(
                          height: 10,
                        ),
                        RichText(
                            textAlign: TextAlign.justify,
                            text: TextSpan(
                                text: 'Your app version ',
                                style: const TextStyle(
                                  fontSize: 16,
                                  color: Colors.black,
                                ),
                                children: <TextSpan>[
                                  TextSpan(
                                      text: widget.apkVersion,
                                      style: const TextStyle(
                                          color: primary,
                                          fontWeight: FontWeight.bold)),
                                  const TextSpan(
                                      text:
                                          " did not match with the latest version ",
                                      style: TextStyle(color: Colors.black)),
                                  TextSpan(
                                      text: widget.currenVersion.toString(),
                                      style: const TextStyle(
                                          color: primary,
                                          fontWeight: FontWeight.bold)),
                                  const TextSpan(
                                      text:
                                          ". Download the app latest version to procceed using the uniT-App.",
                                      style: TextStyle(color: Colors.black)),
                                ])),
                        const SizedBox(
                          height: 12.0,
                        ),
                        Container(
                          child: downloading
                              ? FittedBox(
                                  child: Text(
                                    'Downloading application $progressRating%',
                                    textAlign: TextAlign.center,
                                    style: Theme.of(context)
                                        .textTheme
                                        .headlineSmall!
                                        .copyWith(fontWeight: FontWeight.bold),
                                  ),
                                )
                              : Container(),
                        ),
                        SizedBox(
                          height: 60,
                          width: MediaQuery.of(context).size.width,
                          child: downloading
                              ? Container()
                              : ElevatedButton.icon(
                                  icon: const Icon(Icons.download),
                                  style: mainBtnStyle(
                                      primary, Colors.transparent, second),
                                  onPressed: () async {
                                    final progress = ProgressHUD.of(context);
                                    progress?.showWithText(
                                      'Please wait...',
                                    );
                                    setState(() {
                                      downloading = true;
                                      progressRating = '0';
                                    });
                                    await openFile();
                                  },
                                  label: const Text(
                                      "Download Latest App Version.")),
                        ),
                      ],
                    ),
                  ),
                ),
              );
            }
            if (state is UserError) {
              showAlert(context, () {
                setState(() {
                  downloading = false;
                });
              });
            }
            return Container();
          },
        ),
        const Positioned(bottom: 0, child: WaveReverse(height: 80))
      ]),
    );
  }

  Future<void> openFile() async {
    try {
      final filePath = await downloadFile();
      await openAPK(filePath);
    } catch (e) {
      print(e.toString());
    }
  }

  Future<void> openAPK(String path) async {
    PermissionStatus result = await Permission.storage.request();
    if (result.isGranted) {
      await EasyAppInstaller.instance.installApk(path);
    }
  }

  Future<String> downloadFile() async {
    final progress = ProgressHUD.of(context);
    final appStorage = await getApplicationDocumentsDirectory();
    try {
      String url = await getCPUArchitecture();
      final response = await dio.download(url, '${appStorage.path}/uniT.apk',
          deleteOnError: true,
          options: Options(
              receiveTimeout: 20000,
              sendTimeout: 20000,
              receiveDataWhenStatusError: true,
              responseType: ResponseType.bytes,
              followRedirects: false,
              validateStatus: (status) {
                return status! < 500;
              }), onReceiveProgress: (recv, total) {
        setState(() {
          progressRating = ((recv / total) * 100).toStringAsFixed(0);
          downloading = true;
        });
        if (progressRating == '100') {
          final progress = ProgressHUD.of(context);
          progress!.dismiss();
          setState(() {
            downloading = false;
            isDownloaded = true;
          });
        }
      });
    } on TimeoutException catch (_) {
      progress!.dismiss();
      showAlert(context, () {
        setState(() {
          downloading = false;
        });
      });
      throw TimeoutException(timeoutError);
    } on SocketException catch (_) {
      progress!.dismiss();
      showAlert(context, () {
        setState(() {
          downloading = false;
        });
      });
      throw const SocketException(timeoutError);
    } on DioError catch (_) {
      progress!.dismiss();
      showAlert(context, () {
        setState(() {
          downloading = false;
        });
      });
      throw TimeoutException(timeoutError);
    } catch (_) {
      progress!.dismiss();
      showAlert(context, () {
        setState(() {
          downloading = false;
        });
      });
      throw TimeoutException(timeoutError);
    }
    return '${appStorage.path}/uniT.apk';
  }
}
