import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flux_localization/flux_localization.dart';
import 'package:provider/provider.dart';

import '../../common/config.dart';
import '../../common/constants.dart';
import '../../common/extensions/extensions.dart';
import '../../models/index.dart'
    show AppModel, Product, ProductWishListModel, UserModel;
import '../../models/product_variant_model.dart';
import '../../modules/dynamic_layout/helper/helper.dart';
import '../../routes/flux_navigate.dart';
import '../../services/index.dart';
import '../base_screen.dart';
import '../common/app_bar_mixin.dart';
import 'widgets/share_product_data_widget.dart';

export 'themes/full_size_image_type.dart';
export 'themes/half_size_image_type.dart';
export 'themes/simple_type.dart';

class ProductDetailScreen extends StatefulWidget {
  final Product? product;
  final String? id;

  const ProductDetailScreen({this.product, this.id});

  static void showMenu(
    BuildContext context,
    Product? product, {
    bool isLoading = false,
  }) {
    final productUrl = product?.permalink ?? '';

    showModalBottomSheet(
      context: context,
      builder: (BuildContext modalContext) {
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            if (Services().widget.enableShoppingCart(product))
              ListTile(
                title: Text(
                  S.of(modalContext).myCart,
                  textAlign: TextAlign.center,
                ),
                onTap: () {
                  Navigator.of(modalContext).pop();
                  FluxNavigate.pushNamed(
                    RouteList.cart,
                    forceRootNavigator: true,
                    context: context,
                  );
                },
              ),
            ListTile(
              title: Text(
                S.of(modalContext).showGallery,
                textAlign: TextAlign.center,
              ),
              onTap: () {
                Navigator.of(modalContext).pop();
                context.openImageGallery(
                  isDialog: false,
                  images: product?.images,
                );
              },
            ),
            if (!isLoading && product != null)
              ListTile(
                title: Text(
                  S.of(modalContext).saveToWishList,
                  textAlign: TextAlign.center,
                ),
                onTap: () {
                  Provider.of<ProductWishListModel>(
                    context,
                    listen: false,
                  ).toggleWishlist(product);
                  Navigator.of(modalContext).pop();
                },
              ),

            if (kProductDetail.allowShareProductData &&
                !isLoading &&
                product != null)
              ListTile(
                title: Text(
                  S.of(modalContext).shareProductData,
                  textAlign: TextAlign.center,
                ),
                onTap: () {
                  Navigator.of(context).pop();
                  _shareProductDataDialog(context, product);
                },
              ),

            // Share feature not supported in Notion. Dont care Strapi because
            // it does not have permalink
            if (dynamicLinkConfig.allowShareLink &&
                productUrl.isNotEmpty &&
                !ServerConfig().isNotion)
              ListTile(
                title: Text(
                  S.of(modalContext).shareProductLink,
                  textAlign: TextAlign.center,
                ),
                onTap: () {
                  Navigator.of(modalContext).pop();
                  context.shareLink(
                    productUrl,
                    title: product?.name,
                    image: product?.imageFeature,
                    description: product?.shareDescription,
                  );
                },
              ),
            Container(
              height: 1,
              decoration: const BoxDecoration(color: kGrey200),
            ),
            ListTile(
              title: Text(
                S.of(modalContext).cancel,
                textAlign: TextAlign.center,
              ),
              onTap: () {
                Navigator.of(modalContext).pop();
              },
            ),
          ],
        );
      },
    );
  }

  static Future<void> _shareProductDataDialog(
    BuildContext context,
    Product? product,
  ) {
    return showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return ShareProductDataWidget(product: product);
      },
    );
  }

  @override
  BaseScreen<ProductDetailScreen> createState() => _ProductDetailPageState();
}

class _ProductDetailPageState extends BaseScreen<ProductDetailScreen>
    with AppBarMixin {
  Product? product;
  bool _isProductInfoLoading = true;
  bool _isChecking = Services().widget.enableMembershipUltimate;
  String? _checkingErrorMessage;
  String? _checkingErrorSubMessage;
  final ScrollController _scrollController = ScrollController();

  final ProductVariantModel _productVariantModel = ProductVariantModel();

  @override
  Future<void> afterFirstLayout(BuildContext context) async {}

  @override
  void initState() {
    screenScrollController = _scrollController;
    WidgetsBinding.instance.endOfFrame.then((_) async {
      if (!mounted) return;

      if (widget.product is Product) {
        final isListing = widget.product?.isListing != false;

        product = widget.product;
        _productVariantModel.initWithProduct(product!);

        if (!isListing) {
          final check = await _checkProductPermission(product);
          if (check) {
            product = await Services().widget.getProductDetail(
              context,
              product,
            );
            _productVariantModel.updateValues(product: product);
          }
        }
      } else if (widget.id != null) {
        product = await Services().api.getProduct(widget.id);
        _productVariantModel.updateValues(product: product);

        final isListing = product?.isListing != false;

        if (!isListing) {
          await _checkProductPermission(product);
        }
      }

      if (mounted) {
        setState(() {
          _isProductInfoLoading = false;
        });
      }
    });
    super.initState();
  }

  Future<bool> _checkProductPermission(Product? p) async {
    if (Services().widget.enableMembershipUltimate &&
        (p?.isRestricted ?? false)) {
      setState(() {
        _isChecking = true;
      });
      final cookie = Provider.of<UserModel>(
        context,
        listen: false,
      ).user?.cookie;
      try {
        final check = await Services().api.checkProductPermission(
          p?.id ?? '0',
          cookie,
        );
        setState(() {
          _isChecking = false;
        });
        return check == true;
      } catch (e) {
        var error = '';
        switch (e.toString()) {
          case 'blocked':
            error = S.of(context).noPermissionForCurrentRole;
            break;

          case 'expired':
            error = S.of(context).productExpired;
            break;

          default:
            error = e.toString();
        }
        setState(() {
          _isChecking = false;
          _checkingErrorMessage = error;
        });
        return false;
      }
    }
    if (Services().widget.enableWooCommerceWholesalePrices &&
        (p?.isRestricted ?? false)) {
      setState(() {
        _isChecking = false;
        _checkingErrorMessage = S.of(context).noPermissionToViewProduct;
        _checkingErrorSubMessage = S.of(context).noPermissionToViewProductMsg;
      });
      return false;
    } else {
      setState(() {
        _isChecking = false;
      });
      return true;
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _productVariantModel.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (product?.id == null) {
      return _renderNotAvailableProduct();
    }

    if (_isChecking || (_checkingErrorMessage?.isNotEmpty ?? false)) {
      return _renderCheckingErrorCase();
    }

    return _renderContent();
  }

  Widget _renderContent() {
    var layoutType = Provider.of<AppModel>(context).productDetailLayout;
    final isDesktop = Layout.isDisplayDesktop(context);

    var layout = Services().widget.renderDetailScreen(
      context,
      product!,
      layoutType,
      _isProductInfoLoading,
      scrollController: _scrollController,
      isDesktop: isDesktop,
    );

    if (isDesktop) {
      layout = Scaffold(body: layout);
    } else {
      layout = Scaffold(
        resizeToAvoidBottomInset: false,
        body: Column(
          children: [
            if (showAppBar(RouteList.productDetail)) appBarWidget,
            Expanded(
              child: MediaQuery(
                data: MediaQuery.of(context).copyWith(
                  padding: showAppBar(RouteList.productDetail)
                      ? EdgeInsets.zero
                      : null,
                ),
                child: layout,
              ),
            ),
          ],
        ),
      );
    }

    return GestureDetector(
      onTap: () {
        var currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus) {
          currentFocus.unfocus();
        }
      },
      child: ChangeNotifierProvider.value(
        value: _productVariantModel,
        child: layout,
      ),
    );
  }

  Widget _renderNotAvailableProduct() {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.surface,
      appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0.0),
      body: Center(
        child: _isProductInfoLoading
            ? kLoadingWidget(context)
            : Text(S.of(context).notFound),
      ),
    );
  }

  Widget _renderCheckingErrorCase() {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.surface,
      appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0.0),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 15),
        child: Center(
          child: (_checkingErrorMessage?.isNotEmpty ?? false)
              ? Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Image.asset(kWarning, height: 60),
                    const SizedBox(height: 30),
                    Text(
                      _checkingErrorMessage!,
                      textAlign: TextAlign.center,
                      style: Theme.of(context).textTheme.headlineSmall
                          ?.copyWith(
                            fontSize: 18,
                            color: Theme.of(context).colorScheme.error,
                            fontWeight: FontWeight.bold,
                          ),
                    ),
                    const SizedBox(height: 6),
                    if (_checkingErrorSubMessage != null)
                      Text(
                        _checkingErrorSubMessage!,
                        textAlign: TextAlign.center,
                        style: Theme.of(
                          context,
                        ).textTheme.headlineSmall?.copyWith(fontSize: 14),
                      ),
                  ],
                )
              : kLoadingWidget(context),
        ),
      ),
    );
  }
}
