import 'dart:ui';

import 'package:auto_size_text/auto_size_text.dart';
import 'package:design/design.dart';
import 'package:guru_app/financial/iap/iap_model.dart';
import 'package:guru_app/guru_app.dart';
import 'package:guru_ui/guru_widget.dart';
import 'package:guru_ui/localizations/l10n/generated/app_localizations.dart';
import 'package:guru_ui/localizations/ui_strings.dart';
import 'package:guru_ui/pages/subscription/subscription_card.dart';
import 'package:guru_ui/pages/subscription/subscription_controller.dart';
import 'package:guru_widgets/button/single_tap_widget.dart';
import 'package:guru_widgets/pages/webview/guru_webview_page.dart';
import 'package:guru_widgets/theme/guru_theme.dart';
import 'package:guru_popup/guru_popup.dart';
import 'package:guru_utils/router/router.dart';

part 'subscription_page.g.dart';

@DesignSpec(width: 750, height: 1624)
abstract class SubscriptionDesignSpec implements BasicDesignSpec {
  @SpecEdgeInsets.only(
      start: SpecWidth(40), end: SpecWidth(40), top: SpecStatusBarHeight(50))
  EdgeInsetsDirectional get appBarMargin;

  @CombinedSpec(SpecHeight(88), SpecStatusBarHeight(50))
  double get appBarHeight;

  @SpecHeight(48)
  double get closeIconSize;

  @SpecAbsoluteFontSize(24, consistent: true)
  double get restoreFontSize;

  @SpecEdgeInsets.only(
      top: SpecHeight(24, consistent: true),
      bottom: SpecNavigationBarHeight(30),
      start: SpecWidth(32),
      end: SpecWidth(32))
  EdgeInsetsDirectional get bottomCardsPadding;

  @SpecHeight(48, consistent: true)
  double get premiumCardsBottomSpacing;

  @SpecSize(SpecWidth(630), SpecHeight(104))
  Size get buttonSize;

  @SpecEdgeInsets.only(top: SpecHeight(28), bottom: SpecHeight(32))
  EdgeInsetsDirectional get policyPadding;

  @SpecAbsoluteFontSize(20)
  double get policyFontSize;

  @NestedSpec(242, 320)
  SubscriptionMainCardDesignSpec get mainCardSpec;

  @NestedSpec(206, 268)
  SubscriptionEdgeCardDesignSpec get edgeCardSpec;

  @NestedSpec(650, 124)
  SubscriptionListCardDesignSpec get listCardSpec;

  @SpecHeight(22)
  double get listCardBottomSpacing;

  static SubscriptionDesignSpec get() => _SubscriptionDesignSpec.get();
}

enum SubscriptionCardType { edge, main, list }

class SubscriptionCardStyle {
  final Decoration? decoration;
  final Color? cardTitleColor;
  final Color? cardSubTitleColor;
  final Color? cardThenColor;
  final Color? cardPriceColor;

  SubscriptionCardStyle(
      {this.decoration,
      this.cardTitleColor,
      this.cardSubTitleColor,
      this.cardThenColor,
      this.cardPriceColor});
}

class SubscriptionTheme {
  final Color? backgroundColor;
  final Decoration? bottomDecoration;
  final SubscriptionCardStyle? cardStyle;
  final SubscriptionCardStyle? activeCardStyle;
  final GuruButtonStyle buttonStyle;

  static SubscriptionTheme defaultTheme =
      SubscriptionTheme(buttonStyle: GuruButtonStyle.neutral);

  SubscriptionTheme(
      {this.backgroundColor,
      this.bottomDecoration,
      this.cardStyle,
      this.activeCardStyle,
      required this.buttonStyle});
}

class SubscriptionCardItem {
  // final IapProduct productId;
  final String title;
  final String? subTitle;
  final String? thenTexg;
  final String price;
  final String? labelImage;
  final String? labelText;
  final String? buttonText;
  final SubscriptionCardType type;

  SubscriptionCardItem({
    // required this.productId,
    required this.title,
    this.subTitle,
    this.thenTexg,
    required this.price,
    this.labelText,
    this.labelImage,
    this.buttonText,
    this.type = SubscriptionCardType.edge,
  });
}

class _UIHolder {
  ThemeData? _theme;
  GuruThemeData? _guruTheme;
  SubscriptionTheme? _subscriptionTheme;

  late SubscriptionDesignSpec _designSpec;
  late AppLocalizations appStrings;

  _UIHolder();

  void attach(BuildContext context) {
    _theme ??= Theme.of(context);
    _guruTheme ??= GuruTheme.of(context);
    _subscriptionTheme ??= _guruTheme?.getCustomTheme<SubscriptionTheme>(
            SubscriptionTheme.defaultTheme.runtimeType) ??
        SubscriptionTheme.defaultTheme;
    _designSpec = SubscriptionDesignSpec.get();
    appStrings = UIStrings.get();
  }
}

mixin _UIData {
  final _UIHolder _uiHolder = _UIHolder();

  ThemeData get theme => _uiHolder._theme ?? ThemeData();

  GuruThemeData get guruTheme => _uiHolder._guruTheme ?? GuruThemeData();

  GuruColorScheme get colorScheme => guruTheme.colorScheme;

  SubscriptionTheme get subscriptionTheme =>
      _uiHolder._subscriptionTheme ?? SubscriptionTheme.defaultTheme;

  SubscriptionDesignSpec get designSpec => _uiHolder._designSpec;

  AppLocalizations get appStrings => _uiHolder.appStrings;
}

class SubscriptionPage extends GetWidget<SubscriptionController> with _UIData {
  final List<SubscriptionCardItem> items;
  final Widget Function(BuildContext) contentBuilder;

  SubscriptionPage(
      {super.key, required this.items, required this.contentBuilder});

  Widget _buildPremiumCards(BuildContext context, int index) {
    bool hasListItem = false;
    for (var item in items) {
      if (item.type == SubscriptionCardType.list) {
        hasListItem = true;
      }
    }
    final List<Widget> widgets = [];
    for (var i = 0; i < items.length; i++) {
      final selected = i == index;
      if (hasListItem) {
        widgets.add(SubscriptionListCard(
          model: SubscriptionListCardModel(
              cardItem: items[i],
              designSpec: designSpec.listCardSpec,
              subscriptionTheme: subscriptionTheme,
              onTap: () {
                controller.updateSelectedProductIndex(i);
              },
              selected: selected,
              product: null),
        ));
        if (i != items.length - 1) {
          widgets.add(SizedBox(height: designSpec.listCardBottomSpacing));
        }
      } else {
        if (items[i].type == SubscriptionCardType.edge) {
          widgets.add(SubscriptionEdgeCard(
            model: SubscriptionEdgeCardModel(
                cardItem: items[i],
                designSpec: designSpec.edgeCardSpec,
                subscriptionTheme: subscriptionTheme,
                onTap: () {
                  controller.updateSelectedProductIndex(i);
                },
                selected: selected,
                product: null),
          ));
        } else {
          widgets.add(SubscriptionMainCard(
            model: SubscriptionMainCardModel(
                cardItem: items[i],
                designSpec: designSpec.mainCardSpec,
                subscriptionTheme: subscriptionTheme,
                onTap: () {
                  controller.updateSelectedProductIndex(i);
                },
                selected: selected,
                product: null),
          ));
        }
      }
    }
    return Padding(
        padding: EdgeInsets.only(bottom: designSpec.premiumCardsBottomSpacing),
        child: hasListItem
            ? Column(
                children: widgets,
              )
            : Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: widgets,
              ));
  }

  Widget _buildBottom(BuildContext context) {
    return Container(
      decoration: subscriptionTheme.bottomDecoration ??
          const BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: [Color(0x00121212), Color(0xFF121212), Color(0xFF121212)],
              stops: [0.0, 55 / 584, 1.0],
            ),
          ),
      padding: designSpec.bottomCardsPadding,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          StreamBuilder<int>(
            stream: controller.observableSelectProductIndex,
            builder: (context, snapshot) {
              final int index = snapshot.data ?? 1;
              return _buildPremiumCards(context, index);
            },
          ),
          StreamBuilder<int>(
            stream: controller.observableSelectProductIndex,
            builder: (context, snapshot) {
              final int index = snapshot.data ?? 1;
              return GuruButton(
                size: designSpec.buttonSize,
                sizeSpec: GuruButtonSizeSpec.s1,
                action: items[index].buttonText ?? 'Buy',
                onPressed: () {
                  // final selectedProduct = items[index].productId;
                  // controller.purchase(selectedProduct, selectedProduct.offerId);
                },
              );
            },
          ),
          Padding(
            padding: designSpec.policyPadding,
            child: _buildPolicy(),
          ),
        ],
      ),
    );
  }

  Widget _buildContent(BuildContext context) {
    return Stack(fit: StackFit.expand, children: [
      SingleChildScrollView(
        child: contentBuilder(context),
      ),
      Align(
        alignment: Alignment.bottomCenter,
        child: _buildBottom(context),
      ),
      Align(
          alignment: Alignment.topCenter,
          child: Container(
            width: designSpec.measuredSize.width,
            height: designSpec.appBarHeight,
            padding: designSpec.appBarMargin,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                TapWidget(
                  onTap: () {
                    RouteCenter.instance.back();
                  },
                  child: guruTheme.iconScheme.closeIcon != null
                      ? Image.asset(
                          guruTheme.iconScheme.closeIcon!,
                          width: designSpec.closeIconSize,
                          height: designSpec.closeIconSize,
                          fit: BoxFit.fill,
                        )
                      : Icon(
                          Icons.close,
                          size: designSpec.closeIconSize,
                          color:
                              colorScheme.primaryContentColor ?? Colors.white,
                        ),
                ),
                TapWidget(
                  onTap: () {},
                  child: Text(
                    'restore',
                    style: TextStyle(
                      color: colorScheme.primaryContentColor ?? Colors.white,
                      fontSize: designSpec.restoreFontSize,
                      fontWeight: GuruTheme.fwMedium,
                    ),
                  ),
                ),
              ],
            ),
          ))
    ]);
  }

  @override
  Widget build(BuildContext context) {
    _uiHolder.attach(context);

    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: Scaffold(
        backgroundColor: subscriptionTheme.backgroundColor ??
            colorScheme.backgroundColor ??
            const Color(0xFF121212),
        body: _buildContent(context),
      ),
    );
  }

  Widget _buildPolicy() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        _textLink(
          text: 'privacyPolicy',
          // text: appStrings.privacyPolicy,
          url: GuruApp.instance.details.policyUrl,
          onAfterTap: () {
            GuruAnalytics.instance
                .logEventEx("settings", itemName: "privacy_clk");
          },
        ),
        Text(
          " & ",
          style: TextStyle(
            fontSize: designSpec.policyFontSize,
            color: const Color(0x66FFFFFF),
            fontWeight: GuruTheme.fwRegular,
          ),
        ),
        _textLink(
          text: 'termsOfService',
          // text: appStrings.termsOfService,
          url: GuruApp.instance.details.termsUrl,
          onAfterTap: () {
            GuruAnalytics.instance.logEventEx("settings", itemName: "tos_clk");
          },
        )
      ],
    );
  }

  Widget _textLink(
      {required String text, required String url, VoidCallback? onAfterTap}) {
    return TapWidget(
      child: AutoSizeText(
        text,
        stepGranularity: 0.1,
        minFontSize: 5,
        maxLines: 1,
        style: TextStyle(
          fontSize: designSpec.policyFontSize,
          color: const Color(0x66FFFFFF),
          decoration: TextDecoration.underline,
          fontWeight: GuruTheme.fwRegular,
        ),
      ),
      onTap: () {
        GuruPopup.instance.showDialog(
            widget: GuruWebviewPage(url: Uri.dataFromString(url), title: text),
            useSafeArea: false);
        onAfterTap?.call();
      },
    );
  }
}
