

import 'dart:io';

import 'package:bus_infotainment/audio_cache.dart';
import 'package:bus_infotainment/backend/live_information.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:shared_preferences/shared_preferences.dart';

class InitialStartup extends StatefulWidget {

  @override
  State<InitialStartup> createState() => _InitialStartupState();
}

class _InitialStartupState extends State<InitialStartup> {
  int _page = 0;

  @override
  Widget build(BuildContext context) {

    if (_page == 0 && !kIsWeb) {
      _page = 1;
    }

    return Scaffold(

      body: [
        _page1(this),
        _page2(this),
        _page3(this)
      ][_page],

    );

  }

  void setPage(int page) {
    setState(() {
      _page = page;
    });
  }
}

abstract class InitialStartupPage extends StatefulWidget {

  _InitialStartupState parent;

  InitialStartupPage(this.parent);

}

// Cookies page - only for web
class _page1 extends InitialStartupPage {

  _page1(super.parent);

  @override
  State<_page1> createState() => _page1State();
}

class _page1State extends State<_page1> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(

      padding: EdgeInsets.all(32),

      alignment: Alignment.center,

      child: Column(

        mainAxisSize: MainAxisSize.min,

        children: [

          Text(
            "Cookies",
            style: TextStyle(
              fontSize: 32,
              fontWeight: FontWeight.w600,
            )
          ),

          Text(
            "This website uses first-party cookies for the storage of user data. These cookies are necessary for the functioning of the site and help us provide you with a better browsing experience. By using this website, you consent to the use of these cookies.",
            textAlign: TextAlign.center,
          ),

          SizedBox(
            height: 8,
          ),

          ShadButton(
            onPressed: () {
              widget.parent.setPage(1);
            },
            text: Text(
              "I understand and agree"
            ),
          )



        ],

      )

    );
  }
}

// Permission request page
class _page2 extends InitialStartupPage {

  _page2(super.parent);

  @override
  State<_page2> createState() => _page2State();
}

class _page2State extends State<_page2> {

  Future<bool> _allPermissionsGranted() async {

    List<bool> perms = [];

    perms.addAll([
      await Permission.manageExternalStorage.isGranted,
      await Permission.location.isGranted
    ]);

    return !perms.contains(false);
  }

  @override
  Widget build(BuildContext context) {

    return Container(

        padding: EdgeInsets.all(16),

        alignment: Alignment.center,



        child: SizedBox(

          width: double.infinity,

          child: Column(

            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,

            children: [

              Text(
                "Permissions",
                style: TextStyle(
                  fontSize: 32,
                  fontWeight: FontWeight.w600,
                )
              ),

              SizedBox(
                height: 16,
              ),

              ShadCard(
                width: double.infinity,
                title: Text(
                  "Location",
                ),
                description: Text(
                  "Your location is required for automatically updating your nearest bus stop."
                ),
                content: Container(
                  child: Column(
                    children: [

                      SizedBox(
                        height: 4,
                      ),

                      FutureBuilder(
                        future: Permission.location.isGranted,
                        builder: (context, val) {
                          bool isEnabled = true;
                          String text = "Request permission";
                          Color color = Colors.white;

                          if (val.hasData) {
                            isEnabled = !val.data!;
                          }
                          if (!isEnabled) {
                            text = "Permission granted!";
                            color = Colors.green.shade400;
                          }

                          return ShadButton(
                            text: Text(text),
                            onPressed: () async {
                              await Permission.location.request();
                              setState(() {

                              });
                            },
                            enabled: isEnabled,
                            backgroundColor: color,
                          );
                        },
                      ),
                    ],
                  ),
                ),
              ),

              SizedBox(
                height: 16,
              ),

              ShadCard(
                width: double.infinity,
                title: Text(
                  "Storage",
                ),
                description: Text(
                  "Storage access is required to access recorded announcements."
                ),
                content: Container(
                  child: Column(
                    children: [

                      SizedBox(
                        height: 4,
                      ),

                      FutureBuilder(
                        future: Permission.manageExternalStorage.isGranted,
                        builder: (context, val) {
                          bool isEnabled = true;
                          String text = "Request permission";
                          Color color = Colors.white;

                          if (val.hasData) {
                            isEnabled = !val.data!;
                          }
                          if (!isEnabled) {
                            text = "Permission granted!";
                            color = Colors.green.shade400;
                          }

                          return ShadButton(
                            text: Text(text),
                            onPressed: () async {
                              await Permission.manageExternalStorage.request();
                              setState(() {

                              });
                            },
                            enabled: isEnabled,
                            backgroundColor: color,
                          );
                        },
                      )
                    ],
                  ),
                ),
              ),

              SizedBox(
                height: 16,
              ),

              FutureBuilder(
                future: _allPermissionsGranted(),
                builder: (context, val) {
                  bool isEnabled = true;
                  String text = "Continue";
                  Color color = Colors.white;

                  if (val.hasData) {
                    isEnabled = val.data!;
                  }
                  if (!isEnabled) {
                    text = "Grant all permissions before continuing";
                  }

                  return ShadButton(
                    text: Text(text),
                    onPressed: () async {
                      widget.parent.setPage(2);
                    },
                    enabled: isEnabled,
                    backgroundColor: color,
                    width: double.infinity,
                  );
                },
              )

            ],
          ),
        )

    );

  }
}

class _page3 extends InitialStartupPage {
  _page3(super.parent);

  @override
  State<_page3> createState() => _page3State();
}

class _page3State extends State<_page3> {

  bool _loadingAudio = false;

  Future<bool> _announcementsUploaded() async {
    try {
      Uint8List bytes = await LiveInformation().announcementModule.getBundleBytes();
      return true;
    } catch (e) {
      return false;
    }

  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(

      padding: EdgeInsets.all(16),

      alignment: Alignment.center,

      child: SizedBox(

        width: double.infinity,

        child: Column(

          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,

          children: [

            Text(
              "Prerequisites",
              style: TextStyle(
                fontSize: 32,
                fontWeight: FontWeight.w600,
              )
            ),

            SizedBox(
              height: 16,
            ),

            ShadCard(
              width: double.infinity,
              title: Text(
                "Announcement files",
              ),
              description: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    "You are required to upload the London iBus announcement files. These files can be acquire by submitting a request to TfL under the Freedom of Information Act (2000)"
                  ),
                  SizedBox(
                    height: 4,
                  ),
                  Text(
                    "Please upload a zip file."
                  )
                ],
              ),
              content: Container(
                child: Column(
                  children: [

                    SizedBox(
                      height: 4,
                    ),

                    if (!_loadingAudio)
                    FutureBuilder(
                      future: _announcementsUploaded(),
                      builder: (context, val) {
                        bool isEnabled = true;
                        String text = "Upload file";
                        Color color = Colors.white;

                        if (val.hasData) {
                          isEnabled = !val.data!;
                        }
                        if (!isEnabled) {
                          text = "File uploaded!";
                          color = Colors.green.shade400;
                        }

                        return ShadButton(
                          text: Text(text),
                          onPressed: () async {

                            setState(() {
                              _loadingAudio = true;
                            });

                            FilePickerResult? result = await FilePicker.platform.pickFiles(
                              type: FileType.custom,
                              allowedExtensions: [
                                "zip"
                              ]
                            );



                            if (result != null) {
                              late Uint8List bytes;

                              if (kIsWeb) {
                                bytes = result.files.single.bytes!;
                              } else {
                                File file = File(result.files.single.path!);

                                bytes = file.readAsBytesSync();
                              }

                              LiveInformation().announcementModule.setBundleBytes(bytes);

                              AnnouncementCache cache = LiveInformation().announcementModule.announcementCache;

                              if (!kIsWeb) {

                                // Use shared preferences to store the file location
                                SharedPreferences prefs = await SharedPreferences.getInstance();

                                prefs.setString("AnnouncementsFileLocation", result.files.single.path!);
                              }

                              // load a random announcement to ensure that the file is usable
                              await cache.loadAnnouncementsFromBytes(bytes, ["S_WALTHAMSTOW_CENTRAL_001.mp3"]);

                              setState(() {
                                _loadingAudio = false;
                              });

                            } else {
                              setState(() {
                                _loadingAudio = false;
                              });
                            }


                          },
                          enabled: isEnabled,
                          backgroundColor: color,
                        );
                      },
                    )
                    else
                      CircularProgressIndicator(),


                  ],
                ),
              ),
            ),

            SizedBox(
              height: 16,
            ),

            FutureBuilder(
              future: _announcementsUploaded(),
              builder: (context, val) {
                bool isEnabled = true;
                String text = "Continue";
                Color color = Colors.white;

                if (val.hasData) {
                  isEnabled = val.data!;
                }
                if (!isEnabled) {
                  text = "Complete the prerequisites to continue";
                }

                return ShadButton(
                  text: Text(text),
                  onPressed: () async {

                    showShadDialog(
                      context: context,
                      builder: (context) => ShadDialog.alert(
                        title: Text("You're all setup"),
                        description: Text("You can now continue to the application. \nTry not to annoy anyone on the bus! ;)"),
                        actions: [
                          ShadButton(
                            text: Text("Continue to application"),
                            onPressed: () {
                              Navigator.pushNamed(context, "/");
                            },
                          )
                        ],
                      ),
                      barrierDismissible: false
                    );

                  },
                  enabled: isEnabled,
                  backgroundColor: color,
                  width: double.infinity,
                );
              },
            )

          ],

        ),
      )

    );
  }
}