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

import 'package:design/design.dart';
import 'package:flutter/material.dart';
import 'package:guru_rating/core/dialog_utils.dart';
import 'package:guru_rating/page/going_store_loading_page.dart';
import 'package:guru_rating/page/ios_thankyou_page.dart';
import 'package:guru_rating/page/rating_design_spec.dart';
import 'package:guru_rating/page/rating_result.dart';
import 'package:guru_rating/ratingbar/rating_bar.dart';
import 'package:guru_utils/extensions/extensions.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_widgets/common/flexible_container.dart';
import 'package:guru_widgets/common/spacer.dart';
import 'package:guru_widgets/guru_widgets.dart';

import 'rating_style.dart';

class RatingPage extends StatefulWidget {
  final VoidCallback? initialCallback;
  final RatingStyle ratingStyle;
  final GoingStoreStyle goingStoreStyle;
  final VoidCallback goingStoreCallback;
  final IosThankYouStyle iosThankYouStyle;
  final VoidCallback iosFiveStarCallback;

  const RatingPage(
      {Key? key,
      this.initialCallback,
      required this.ratingStyle,
      required this.goingStoreStyle,
      required this.goingStoreCallback,
      required this.iosThankYouStyle,
      required this.iosFiveStarCallback})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => RatingState();
}

class RatingState extends State<RatingPage> {
  final RatingDesignSpec designSpec = RatingDesignSpec.get();

  BehaviorSubject<double> ratingSubject = BehaviorSubject.seeded(-1);

  Stream<double> get observableRating => ratingSubject.stream;
  final TextEditingController editorController = TextEditingController();

  double get rating => ratingSubject.value;

  late RattingButtonTapDelegate delegate = RattingButtonTapDelegate(_onSubmitButtonTap);

  @override
  void initState() {
    super.initState();
    widget.initialCallback?.call();
  }

  @override
  void dispose() {
    super.dispose();
    editorController.dispose();
  }

  void _onSubmitButtonTap() {
    submit();
  }

  Widget _buildCloseButton() {
    return Align(
      alignment: AlignmentDirectional.centerStart,
      child: Padding(
        padding: EdgeInsetsDirectional.only(start: designSpec.step1DialogSpec.closeIconStartSpacing),
        child: CircleButton(
            radius: designSpec.step1DialogSpec.closeIconInkRadius,
            content: Center(
                child: Image.asset(
              widget.ratingStyle.closeImage,
              width: designSpec.step1DialogSpec.closeIconSize,
              height: designSpec.step1DialogSpec.closeIconSize,
              color: widget.ratingStyle.closeImageColor,
            )),
            backgroundColor: Colors.transparent,
            onTapCallback: () {
              Navigator.pop(context, RatingResult.cancel(predicted: rating.toInt()));
            }),
      ),
    );
  }

  Widget _buildRatingBar({double initialRating = 0.0}) {
    return RatingBar(
      initialRating: initialRating,
      direction: Axis.horizontal,
      allowHalfRating: false,
      itemCount: 5,
      ratingWidget: RatingWidget(
        full: Image.asset(widget.ratingStyle.ratingFullImage),
        empty: Image.asset(widget.ratingStyle.ratingEmptyImage),
        half: Image.asset(widget.ratingStyle.ratingHalfImage),
      ),
      itemPadding: const EdgeInsets.symmetric(horizontal: 6),
      itemSize: designSpec.step1DialogSpec.ratingItemSize,
      onRatingUpdate: (rating) {
        ratingSubject.addEx(rating);
        if (rating == 5) {
          _processFiveStar();
        }
      },
      maxRating: 5.0,
      minRating: 1.0,
      unratedColor: widget.goingStoreStyle.unRatedColor ?? Theme.of(context).disabledColor,
      // textDirection:TextDirection.RTL,
      glowColor: widget.goingStoreStyle.gLowColor ?? Theme.of(context).primaryColor,
      tapOnlyMode: true,
    );
  }

  Widget _buildStep1(BuildContext context, double rating) {
    return FlexibleContainer(
      radius: designSpec.step1DialogSpec.radius,
      color: widget.ratingStyle.backgroundStyle.backgroundColor,
      gradient: widget.ratingStyle.backgroundStyle.gradient,
      constraints: BoxConstraints(
        minHeight: designSpec.step1DialogSpec.measuredSize.height,
        minWidth: designSpec.step1DialogSpec.measuredSize.width,
        maxWidth: designSpec.step1DialogSpec.measuredSize.width,
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Stack(
            children: [
              Container(
                width: double.infinity,
              ),
              Center(
                child: FlexibleContainer(
                  margin: EdgeInsets.only(top: designSpec.step1DialogSpec.imageTopSpace),
                  borderColor: kDebugMode ? Colors.red : null,
                  width: designSpec.step1DialogSpec.imageAreaSize.width,
                  height: designSpec.step1DialogSpec.imageAreaSize.height,
                  child: Center(
                    child: Image.asset(
                      widget.ratingStyle.step1Image,
                      width: designSpec.step1DialogSpec.imageSize.width,
                      height: designSpec.step1DialogSpec.imageSize.height,
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ),
              PositionedDirectional(
                  start: 0,
                  top: designSpec.step1DialogSpec.closeIconTopSpacing,
                  child: _buildCloseButton()),
            ],
          ),
          Text(
            widget.ratingStyle.step1Title,
            style: TextStyle(
                fontSize: designSpec.step1DialogSpec.titleFontSize,
                color: widget.ratingStyle.titleColor,
                fontWeight: FontWeight.w500),
            strutStyle: const StrutStyle(height: 1.4),
          ),
          SizedSpacer(height: designSpec.step1DialogSpec.ratingStartTopSpacing),
          _buildRatingBar(initialRating: rating > 0 ? rating : 0),
          SizedSpacer(height: designSpec.step1DialogSpec.ratingStartBottomSpacing),
        ],
      ),
    );
  }

  void submit() async {
    if (!mounted) {
      return;
    }
    final predictedRating = rating.toInt();
    Navigator.pop(
        context, RatingResult.submit(predictedRating, feedback: editorController.text.toString()));
    if (predictedRating > 0 && predictedRating < 5) {
      if (editorController.text.isNotEmpty == true) {
        Future.delayed(const Duration(milliseconds: 500), () {
          showIosThankYouDialog(widget.iosThankYouStyle,
              barrierColor: widget.iosThankYouStyle.barrierColor);
        });
      } else {
        showIosThankYouDialog(widget.iosThankYouStyle,
            barrierColor: widget.iosThankYouStyle.barrierColor);
      }
    }
    
  }

  void _processFiveStar() async {
    submit();
    showIosThankYouDialog(widget.iosThankYouStyle,
        barrierColor: widget.iosThankYouStyle.barrierColor);
    if (Platform.isAndroid) {
      Future.delayed(widget.ratingStyle.inAppReViewDelayTime, () {
        widget.goingStoreCallback.call();
      });
    } else {
      widget.iosFiveStarCallback.call();
    }
  }

  Widget _buildStep2(BuildContext context, double rating) {
    final title =
        rating >= 4 ? widget.ratingStyle.step2ThankYouTitle : widget.ratingStyle.step2SorryTitle;

    final emoji =
        rating >= 4 ? widget.ratingStyle.step2ThankYouEmoji : widget.ratingStyle.step2SorryEmoji;
    final summary = rating >= 4
        ? widget.ratingStyle.step2ThankYouSummary.replaceAll("\\n", "\n")
        : widget.ratingStyle.step2SorrySummary.replaceAll("\\n", "\n");

    return FlexibleContainer(
      constraints: BoxConstraints(
        minHeight: designSpec.step2DialogSpec.measuredSize.height,
        minWidth: designSpec.step2DialogSpec.measuredSize.width,
        maxWidth: designSpec.step2DialogSpec.measuredSize.width,
      ),
      radius: designSpec.step1DialogSpec.radius,
      color: widget.ratingStyle.backgroundStyle.backgroundColor,
      gradient: widget.ratingStyle.backgroundStyle.gradient,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedSpacer(
            height: designSpec.step1DialogSpec.closeIconTopSpacing,
          ),
          _buildCloseButton(),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                title,
                style: TextStyle(
                    fontSize: designSpec.step2DialogSpec.titleFontSize,
                    fontWeight: FontWeight.w700,
                    color: widget.ratingStyle.titleColor),
              ),
              Text(
                " ${emoji ?? ""}",
              ),
            ],
          ),
          SizedSpacer(height: designSpec.step2DialogSpec.summaryTopSpacing),
          SizedBox(
            width: designSpec.step2DialogSpec.summaryMaxWidth,
            child: Text(
              summary,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: designSpec.step2DialogSpec.summaryFontSize,
                fontWeight: FontWeight.w500,
                color: widget.ratingStyle.summaryTextColor,
              ),
              strutStyle: const StrutStyle(height: 1.5),
            ),
          ),
          SizedSpacer(height: designSpec.step2DialogSpec.ratingStartTopSpacing),
          _buildRatingBar(initialRating: rating),
          SizedSpacer(height: designSpec.step2DialogSpec.editorBarTopSpacing),
          FlexibleContainer(
            width: designSpec.step2DialogSpec.editorBarSize.width,
            height: designSpec.step2DialogSpec.editorBarSize.height,
            padding: designSpec.step2DialogSpec.editorBarPadding,
            color: widget.ratingStyle.editorBarBackground,
            radius: designSpec.step2DialogSpec.editorBarRadius,
            needClip: true,
            child: TextField(
              scrollPadding: EdgeInsets.zero,
              controller: editorController,
              style: TextStyle(
                  color: widget.ratingStyle.editorTextColor,
                  fontSize: designSpec.step2DialogSpec.editorTextSize,
                  fontWeight: FontWeight.w400),
              decoration: InputDecoration(
                  hintText: widget.ratingStyle.inputHint,
                  hintStyle: TextStyle(
                      fontSize: designSpec.step2DialogSpec.editorTextSize,
                      color: widget.ratingStyle.editorHintColor,
                      fontWeight: FontWeight.w400),
                  border: InputBorder.none),
              minLines: 3,
              maxLines: 6,
              textCapitalization: TextCapitalization.words,
            ),
          ),
          SizedSpacer(height: designSpec.step2DialogSpec.submitTopSpacing),
          widget.ratingStyle.submitButtonStyle != null
              ? GestureDetector(
                  onTap: delegate.onTap,
                  child: FlexibleContainer(
                    width: designSpec.step2DialogSpec.submitButtonSize.width,
                    height: designSpec.step2DialogSpec.submitButtonSize.height,
                    radius: designSpec.step2DialogSpec.submitButtonRadius,
                    color: widget.ratingStyle.submitButtonStyle!.buttonBgColor,
                    alignment: Alignment.center,
                    child: Text(
                      widget.ratingStyle.submitButtonStyle!.buttonText,
                      style: TextStyle(
                        fontSize: designSpec.step2DialogSpec.submitButtonTextSize,
                        color: widget.ratingStyle.submitButtonStyle!.buttonTextColor,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                )
              : widget.ratingStyle.submitButtonBuilder!.call(delegate),
          SizedSpacer(height: designSpec.step2DialogSpec.submitBottomSpacing),
        ],
      ),
    );
  }

  Widget buildContent(BuildContext context) {
    return StreamBuilder<double>(
        stream: observableRating,
        initialData: 0.0,
        builder: (context, snapshot) {
          final rating = snapshot.data ?? 0.0;
          if (rating > 0 && rating < 5) {
            return _buildStep2(context, rating);
          } else {
            return _buildStep1(context, rating);
          }
        });
  }

  Completer showGoingStoreDialog(VoidCallback completeCallback, GoingStoreStyle goingStoreStyle,
      {Color barrierColor = Colors.transparent}) {
    final completer = Completer.sync();
    completer.future.then((_) {
      completeCallback.call();
    }).whenComplete(() {
      Log.v("showGoingStoreDialog dialog!!! completed!");
    }).catchError((error) {
      Log.v("showGoingStoreDialog dialog!!! completed!");
    });

    DialogUtils.showDialog(
      widget: GoingStoreLoadingPage(goingStoreStyle),
      barrierColor: barrierColor,
      animation: DialogAnimation.fadeIn,
    );
    return completer;
  }

  Future showIosThankYouDialog(IosThankYouStyle thankYouStyle,
      {Color? barrierColor = Colors.transparent}) async {
    return DialogUtils.showDialog(
      widget: IosThankYouPage(thankYouStyle),
      barrierColor: barrierColor,
      animation: DialogAnimation.fadeIn,
    );
  }

  @override
  Widget build(BuildContext context) {
    return buildContent(context);
  }
}
