import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:cross_file/cross_file.dart';
import 'package:path_provider/path_provider.dart';

import 'package:boilerplate/core/constant/constants.dart';
import 'package:boilerplate/core/di/injection_init.dart';
import 'package:boilerplate/core/i18n/translations.g.dart';
import 'package:boilerplate/core/styles/my_font.dart';
import 'package:boilerplate/core/utils/navigator_util.dart';
import 'package:boilerplate/core/utils/shared_preferences_util.dart';
import 'package:boilerplate/domain/entities/flavor/flavor_data.dart';
import 'package:boilerplate/domain/usecases/notification/save_fcm_token_use_case.dart';
import 'package:boilerplate/presentation/bloc/landing/bottom_navigation_cubit.dart';
import 'package:boilerplate/presentation/screen/landing/landing_screen.dart';
import 'package:boilerplate/presentation/screen/products/detail/product_detail_screen.dart';
import 'package:boilerplate/presentation/screen/web_view/widgets/menu_drawer.dart';
import 'package:boilerplate/presentation/widgets/base_scaffold.dart';
import 'package:external_app_launcher/external_app_launcher.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:http/http.dart' as http;

import '../../../core/styles/my_dimensions.dart';
import '../../../core/utils/print_utils.dart';
import '../../widgets/custom_transition_route.dart';
import '../../widgets/loading.dart';
import '../contact_us/contact_us_page.dart';
import 'widgets/contact_button.dart';

class WebViewScreen extends StatefulWidget {
  final bool isLanding;
  final String? title;
  final String url;
  final bool isSellerDetail;
  final String email;
  final String phone;

  WebViewScreen({
    Key? key,
    required this.url,
    this.title,
    this.isLanding = false,
    this.isSellerDetail = false,
    this.email = "",
    this.phone = "",
  }) : super(key: key);

  @override
  State<WebViewScreen> createState() => _WebViewScreenState();
}

class _WebViewScreenState extends State<WebViewScreen>
    with AutomaticKeepAliveClientMixin {
  final GlobalKey webViewKey = GlobalKey();
  final String domain = getIt.get<AppFlavorData>().webDomain;
  final CookieManager cookieManager = CookieManager.instance();
  late PullToRefreshController pullToRefreshController;
  int _counter = 0;
  // late final Uint8List _imageFile;
  late File _imageFile;

  //Create an instance of ScreenshotController
  ScreenshotController screenshotController = ScreenshotController();

  late Uri? oldUri;

  InAppWebViewController? webViewController;
  final StreamController<bool> loadingStmCtrl = StreamController<bool>();
  Stream<bool> get loadingStm => loadingStmCtrl.stream;
  bool isLogin = false;

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

    pullToRefreshController = PullToRefreshController(
      options: PullToRefreshOptions(
        color: Colors.blue,
      ),
      onRefresh: () async {
        final url = await webViewController?.getUrl();
        isLogin = false;
        if (Platform.isAndroid) {
          await webViewController?.reload();
        } else if (Platform.isIOS) {
          webViewController?.loadUrl(urlRequest: URLRequest(url: url));
        }
      },
    );

    getLang();
  }

  getLang() async {
    await FirebaseAnalytics.instance.logScreenView(screenName: 'WebviewPage');
  }

  Future<void> onWebViewCreated(InAppWebViewController ctrl) async {
    webViewController = ctrl;

    await setCookieBeforeLoad();

    oldUri = Uri.parse(widget.url);
    print("oldUri ${oldUri}");
    // oldUri = Uri.parse(widget.url);

    webViewController?.loadUrl(
      urlRequest: URLRequest(
        url: oldUri,
        iosHttpShouldHandleCookies: true,
        iosCachePolicy: IOSURLRequestCachePolicy.USE_PROTOCOL_CACHE_POLICY,
      ),
    );
  }

  setCookieBeforeLoad() async {
    final pref = getIt.get<SharedPreferencesUtil>();
    final token = pref.getString(SharedPreferencesUtil.keyWebAccessToken);
    final rfToken = pref.getString(SharedPreferencesUtil.keyWebRefreshToken);

    if (token != null) {
      await cookieManager.setCookie(
        url: Uri.parse(domain),
        name: SharedPreferencesUtil.keyWebAccessToken,
        value: token,
      );
    }

    if (rfToken != null) {
      await cookieManager.setCookie(
        url: Uri.parse(domain),
        name: SharedPreferencesUtil.keyWebRefreshToken,
        value: rfToken,
      );
    }
  }

  Future<void> onLoadStart(InAppWebViewController controller, Uri? url) async {
    loadingStmCtrl.add(true);
  }

  onLoadStop(InAppWebViewController controller, Uri? url) {
    pullToRefreshController.endRefreshing();
    loadingStmCtrl.add(false);
  }

  void onLoadError(
    InAppWebViewController controller,
    Uri? url,
    int code,
    String message,
  ) {
    pullToRefreshController.endRefreshing();
  }

  Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(
    InAppWebViewController controller,
    NavigationAction navigationAction,
  ) async {
    final nextUrl = navigationAction.request.url!;

    // print("my next url : ${nextUrl}");
    // // dPrint("my next path : ${nextUrl.path}");
    // print('my old url : ${oldUri}');
    String getURL = nextUrl.toString();
    if (nextUrl.path == 'blank') {
      return NavigationActionPolicy.ALLOW;
    }

    if (Platform.isIOS && nextUrl.path == '/me') {
      navigationAction.iosWKNavigationType = IOSWKNavigationType.OTHER;
    }

    if ((oldUri != null && oldUri!.path.contains('/login'))) {
      if (nextUrl.path == '/') {
        print('my login success');
        if (Platform.isIOS) {
          await _setToken();
        }
        await _saveToken();

        await _saveFCMToken();

        // await encrytion('', '');
        NavigatorUtil.popToFirstAndReplace(LandingScreem());
        BlocProvider.of<BottomNavigationCubit>(context).changePage(0);

        return NavigationActionPolicy.CANCEL;
      }
    }
    print("nextUrl.path ${nextUrl.path}");
    print("nextUrl ${nextUrl}");
    if (nextUrl.path == '/' && nextUrl.queryParametersAll.length == 0) {
      print("11111111");
      NavigatorUtil.popToFirstAndReplace();
      BlocProvider.of<BottomNavigationCubit>(context).changePage(0);
      return NavigationActionPolicy.CANCEL;
    } else if (oldUri?.path != '/me' &&
        nextUrl.path == '/me' &&
        nextUrl.queryParametersAll.length == 0) {
      print("222222222");

      NavigatorUtil.popToFirstAndReplace();
      BlocProvider.of<BottomNavigationCubit>(context).changePage(4);
      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.path == '/register' &&
        nextUrl.queryParametersAll.length == 0) {
      print("33333333");

      NavigatorUtil.pushToPage(WebViewScreen(
        key: UniqueKey(),
        url: domain + WEB_REGISTER,
      ));
      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.path == "/calendar/u/0/r") {
      print("4444444444");

      if (await canLaunchUrlString(
          'https://calendar.google.com/calendar/u/0/r?mobile=1&pli=1')) {
        launchUrlString(
          'https://calendar.google.com/calendar/u/0/r?mobile=1&pli=1',
          mode: LaunchMode.externalApplication,
        );
      }

      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.path == '/forgot-password' &&
        nextUrl.queryParametersAll.length == 0) {
      print("555555555");

      NavigatorUtil.pushToPage(WebViewScreen(
        key: UniqueKey(),
        url: domain + WEB_FORGOT_PASS,
      ));
      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.host.contains('zoom.us')) {
      print("6666666666");

      launchUrl(nextUrl, mode: LaunchMode.externalApplication);
      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.path.contains('/product')) {
      print("777777777");

      final id = nextUrl.path.split('/').last;

      NavigatorUtil.pushToPage(ProductDetailScreen(prodictId: int.parse(id)));
      return NavigationActionPolicy.CANCEL;
    } else if (widget.isLanding &&
        nextUrl.path.contains('/profile') &&
        nextUrl.path.contains('/edit')) {
      print("8888888888888");

      NavigatorUtil.pushToPage(WebViewScreen(
        key: UniqueKey(),
        title: 'แก้ไขข้อมูลสมาชิก',
        url: domain + nextUrl.path + '?mobile=1',
      ));
      return NavigationActionPolicy.CANCEL;
    } else if (widget.isLanding && nextUrl.path.contains('/offer')) {
      print("99999999999");

      NavigatorUtil.pushToPage(WebViewScreen(
        key: UniqueKey(),
        title: AppLocalizations.menu.offer,
        url: domain + nextUrl.path + '?mobile=1',
      ));
      return NavigationActionPolicy.CANCEL;
    } else if (nextUrl.toString() ==
        "https://eservice.ipthailand.go.th/login") {
      print("101010101010101010");

      final _url = Uri.parse("https://eservice.ipthailand.go.th/login");
      if (!await launchUrl(_url, mode: LaunchMode.externalApplication)) {
        // <--
        throw Exception('Could not launch $_url');
      }

      // if (await canLaunchUrl(Uri.parse(nextUrl.toString()))) {
      //   await launchUrl(Uri.parse(nextUrl.toString()));
      // } else {
      //   if (Platform.isAndroid) {
      //     // Android-specific code
      //     await launchUrl((Uri.parse(
      //         'https://play.google.com/store/apps/details?id=th.go.dopa.bora.dims.ddopa')));
      //   } else if (Platform.isIOS) {
      //     // iOS-specific code
      //     await launchUrl(
      //         (Uri.parse('https://apps.apple.com/th/app/thaid/id1533612248')));
      //   } else {}
      // }

      return await NavigationActionPolicy.ALLOW;
    }

    if (!isLogin &&
        !(nextUrl.path.contains('/mobile/order/booking')) &&
        !(nextUrl.path.contains('/register/store')) &&
        !(nextUrl.path.contains('/forgot-password/send-mail')) &&
        !(nextUrl.path.contains('/api-client/demo/embedded')) &&
        !(nextUrl.path.contains('/plugins/page.php')) &&
        nextUrl.queryParameters['mobile'] == null) {
      if (nextUrl.path == '/login') {
        print("11111111x");

        oldUri = nextUrl;
        isLogin = true;
      }

      final Map<String, String> query = {'mobile': '1'};
      if (nextUrl.queryParametersAll.length > 0) {
        for (var q in nextUrl.queryParametersAll.entries) {
          query.addAll({q.key: q.value[0]});
        }
      } else if (oldUri!.path.contains('/mobile/order/booking')) {
        for (var q in oldUri!.queryParametersAll.entries) {
          query.addAll({q.key: q.value[0]});
        }
      }

      String path = nextUrl.path;

      if (Platform.isIOS &&
          navigationAction.iosWKNavigationType ==
              IOSWKNavigationType.FORM_SUBMITTED) {
        return NavigationActionPolicy.ALLOW;
      }

      loadTo(path, query, nextUrl.toString());

      // navigationAction.request.url = uri;

      // print(navigationAction.request);

      // if (Platform.isIOS) {
      //   navigationAction.iosSourceFrame?.request?.url = uri;
      //   navigationAction.iosTargetFrame?.request?.url = uri;
      // } else if (Platform.isAndroid) {
      //   navigationAction.androidIsRedirect = true;
      // }

      return NavigationActionPolicy.CANCEL;
    }
    // print("nextUrl.path ${nextUrl.path}");
    if (nextUrl.path != 'blank' &&
        !(nextUrl.path.contains('/api-client/demo/embedded')) &&
        !(nextUrl.path.contains('/plugins/page.php'))) {
      oldUri = nextUrl;
    }

    //check when token has refresh token
    await _refreshToken();

    //clear auth token when redirect to login
    if (nextUrl.path.contains('/login')) {
      isLogin = true;
      //   await clearAuth();
    }

    return NavigationActionPolicy.ALLOW;
  }

  loadTo(String path, Map<String, String> query, String goUrL) async {
    print("myPath ${path}");
    print("myPath ${goUrL}");
    // if (path == "/login" &&
    //     oldUri == "https://ipmart.ipthailand.go.th/login?mobile=1" &&
    //     goUrL == "https://eservice.ipthailand.go.th/login") {
    //   final _url = Uri.parse("https://eservice.ipthailand.go.th/login");
    //   if (!await launchUrl(_url, mode: LaunchMode.externalApplication)) {
    //     // <--
    //     throw Exception('Could not launch $_url');
    //   }
    // }
    // else {
    final uri = Uri.parse(domain + path);

    final newUri = Uri(
      scheme: uri.scheme,
      host: uri.host,
      port: uri.port,
      path: uri.path,
      queryParameters: query,
    );
    print('my go url : $newUri');
    webViewController?.loadUrl(
      urlRequest: URLRequest(
        url: newUri,
      ),
    );
  }

  _saveFCMToken() async {
    final pref = getIt.get<SharedPreferencesUtil>();
    await getIt.get<SaveFCMTokenUseCase>().execute(
          pref.getInt(SharedPreferencesUtil.keyUserId)!,
        );
  }

  _setToken() async {
    final cookies = await cookieManager.ios.getAllCookies();

    await Future.forEach(cookies, (Cookie c) {
      cookieManager.setCookie(
        url: Uri.parse(getIt.get<AppFlavorData>().webDomain),
        name: c.name,
        value: c.value,
        domain: c.domain,
        expiresDate: c.expiresDate,
        isHttpOnly: c.isHttpOnly,
        isSecure: c.isSecure,
        sameSite: c.sameSite,
      );
    });
  }

  _saveToken() async {
    List<Cookie> cookies;
    if (Platform.isAndroid) {
      cookies = await cookieManager.getCookies(
          url: Uri.parse(getIt.get<AppFlavorData>().webDomain));
    } else {
      cookies = await cookieManager.ios.getAllCookies();
    }

    final pref = getIt.get<SharedPreferencesUtil>();

    if (cookies.length <= 0) return;

    for (var c in cookies) {
      if (c.name == SharedPreferencesUtil.keyWebAccessToken) {
        pref.putString(SharedPreferencesUtil.keyWebAccessToken, c.value);
      } else if (c.name == SharedPreferencesUtil.keyWebRefreshToken) {
        pref.putString(SharedPreferencesUtil.keyWebRefreshToken, c.value);
      } else if (c.name == SharedPreferencesUtil.keyUserId) {
        Uint8List _bytes = base64Decode(c.value);
        String v = new String.fromCharCodes(_bytes);
        pref.putInt(SharedPreferencesUtil.keyUserId, int.parse(v));
      }
    }
  }

  _refreshToken() async {
    if (isLogin) return;

    List<Cookie> cookies;
    if (Platform.isAndroid) {
      cookies = await cookieManager.getCookies(
          url: Uri.parse(getIt.get<AppFlavorData>().webDomain));
    } else {
      cookies = await cookieManager.ios.getAllCookies();
    }

    final pref = getIt.get<SharedPreferencesUtil>();

    if (cookies.length <= 0) return;

    for (var c in cookies) {
      if (c.name == SharedPreferencesUtil.keyWebAccessToken &&
          c.value !=
              pref.putString(
                  SharedPreferencesUtil.keyWebAccessToken, c.value)) {
        pref.putString(SharedPreferencesUtil.keyWebAccessToken, c.value);
      } else if (c.name == SharedPreferencesUtil.keyWebRefreshToken &&
          c.value !=
              pref.putString(
                  SharedPreferencesUtil.keyWebRefreshToken, c.value)) {
        pref.putString(SharedPreferencesUtil.keyWebRefreshToken, c.value);
      }
    }
  }

  @override
  void dispose() {
    webViewController?.stopLoading();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return WillPopScope(
      onWillPop: () async {
        if (webViewController == null) return false;

        final url = (await webViewController!.getUrl());

        if ((url?.path.split('/offer/').length ?? 0) > 1) {
          final first =
              (await webViewController!.getCopyBackForwardList())!.list!.first;
          webViewController?.goTo(historyItem: first);
          return false;
        }

        if (url!.path.contains('/profile') && url.path.contains('/edit')) {
          return true;
        }

        if (await webViewController!.canGoBack()) {
          webViewController?.goBack();
          return false;
        } else if (ModalRoute.of(context)?.canPop ?? false) {
          return true;
        }

        return true;
      },
      child: BaseScaffold(
        leading: _getBackButton(),
        // onBack: true,
        actions: [
          _menu(),
        ],
        resizeToAvoidBottomInset: false,
        title: widget.title,
        body: Stack(
          children: [
            Container(
              height: widget.email.isNotEmpty || widget.phone.isNotEmpty
                  ? MediaQuery.of(context).size.height - 210
                  : MediaQuery.of(context).size.height,
              color: Colors.white,
              child: InAppWebView(
                key: webViewKey,
                pullToRefreshController: pullToRefreshController,
                gestureRecognizers: Set()
                  ..add(Factory<VerticalDragGestureRecognizer>(
                      () => VerticalDragGestureRecognizer())),
                initialOptions: InAppWebViewGroupOptions(
                  crossPlatform: InAppWebViewOptions(
                    useShouldOverrideUrlLoading: true,
                    disableVerticalScroll: false,
                    supportZoom: false,
                    disableContextMenu: false,
                    javaScriptEnabled: true,
                    javaScriptCanOpenWindowsAutomatically: true,
                    allowFileAccessFromFileURLs: true,
                  ),
                  android: AndroidInAppWebViewOptions(
                    useHybridComposition: true,
                    geolocationEnabled: true,
                  ),
                  ios: IOSInAppWebViewOptions(
                    sharedCookiesEnabled: true,
                    allowsLinkPreview: true,
                    useOnNavigationResponse: true,
                  ),
                ),
                onWebViewCreated: onWebViewCreated,
                onLoadStop: onLoadStop,
                onLoadStart: onLoadStart,
                onLoadError: onLoadError,
                shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
                onReceivedServerTrustAuthRequest:
                    (controller, challenge) async {
                  return ServerTrustAuthResponse(
                    action: ServerTrustAuthResponseAction.PROCEED,
                  );
                },
              ),
            ),
            if (widget.email.isNotEmpty || widget.phone.isNotEmpty)
              Align(
                alignment: Alignment.bottomCenter,
                child: Container(
                  height: 100,
                  padding: EdgeInsets.all(MyDimens.dimen20),
                  decoration: BoxDecoration(
                      gradient: LinearGradient(colors: [
                        Color(0xFFD3CCC6),
                        Color(0xFFAAAAAA),
                      ]),
                      borderRadius: BorderRadius.vertical(
                        top: Radius.circular(10),
                      )),
                  child: Row(
                    children: [
                      Expanded(
                        child: Text(
                          'ติดต่อสอบถามเจ้าของผลงาน',
                          style: MyFont.medium16,
                        ),
                      ),
                      if (widget.email.isNotEmpty)
                        Expanded(
                          child: Container(
                            child: ContactButton(
                              iconAsset: 'assets/icons/ic_mail.svg',
                              title: 'อีเมล',
                              onPressed: () {
                                launchUrlString('mailto://${widget.email}');
                              },
                            ),
                          ),
                        ),
                      if (widget.email.isNotEmpty && widget.phone.isNotEmpty)
                        SizedBox(width: MyDimens.dimen10),
                      if (widget.phone.isNotEmpty)
                        Expanded(
                          child: ContactButton(
                            iconAsset: 'assets/icons/ic_phone.svg',
                            title: 'โทร',
                            onPressed: () {
                              launchUrlString('tel://${widget.phone}');
                            },
                          ),
                        ),
                    ],
                  ),
                ),
              ),
            StreamBuilder<bool>(
              initialData: false,
              stream: loadingStm,
              builder: (context, snapshot) {
                if (snapshot.data!) {
                  return LoadingScreen();
                } else {
                  return Container();
                }
              },
            )
          ],
        ),
      ),
    );
  }

  encrytion(String id, String status) async {
    String url = "https://ipmart.ipthailand.go.th/api/auth/login";
    Object body = {"email": "pd7837971@gmail.com", "password": "P@ssw0rd"};
    // print(body);
    var response = await http.post(
      Uri.parse(url),
      body: body,
    );
    // print(url);
    // print("encrytion body=> ${body}");
    var res = json.decode(response.body)['result']['profile']['name'];
    print("response.body encrytion=> ${response.body}");
    print("response.body encrytion=> ${res}");
    print("================================");
    if (response.statusCode == 200) {
      // decrytion(json.decode(response.body)['data']);
      print("200");

      return res.toString();
    } else {
      // print(loginResult.errorMessage);
    }
  }

  Widget? _getBackButton() {
    if (widget.isLanding) {
      return Container();
    }

    return IconButton(
      onPressed: () async {
        if (webViewController == null) return;

        final url = await webViewController!.getUrl();

        if ((url?.path.split('/offer/').length ?? 0) > 1) {
          final first =
              (await webViewController!.getCopyBackForwardList())!.list!.first;
          webViewController?.goTo(historyItem: first);
          return;
        }

        if (url!.path.contains('/profile') && url.path.contains('/edit')) {
          Navigator.pop(context);
          return;
        }
        if (widget.title == 'การนัดหมายเจรจา' ||
            widget.title == "Business Matching") {
          NavigatorUtil.pushReplaceToPage(LandingScreem());
          // Navigator.pop(context);
        }
        if (await webViewController!.canGoBack()) {
          webViewController?.goBack();
          return;
        }
        if (widget.title == "การแจ้งเตือน" || widget.title == "Notification") {
          NavigatorUtil.pushReplaceToPage(LandingScreem());
        } else if (ModalRoute.of(context)?.canPop ?? false) {
          Navigator.pop(context);
        } else {}
      },
      icon: SvgPicture.asset(
        'assets/icons/ic_back_button.svg',
        color: Colors.white,
        width: MyDimens.dimen24,
        height: MyDimens.dimen24,
      ),
    );
  }

  Widget _menu() {
    if (!widget.isLanding) {
      return Container();
    }
    return Builder(builder: (context) {
      return IconButton(
        onPressed: () async {
          // MenuDrawer
          SharedPreferences prefs = await SharedPreferences.getInstance();

          Navigator.push(
            context,
            CustomTransitionRoute(
              builder: (_) => Drawer(
                backgroundColor: Colors.transparent,
                child: MenuDrawer(myLang: prefs.getString('lang').toString()),
              ),
              begin: Offset(1, 0),
              end: Offset(0, 0),
            ),
          );
        },
        icon: Icon(
          Icons.menu,
          size: MyDimens.dimen24,
          color: Colors.white,
        ),
      );
    });
  }

  @override
  bool get wantKeepAlive => true;
}
