refund_explanation_bottom_sheet.dart 8.76 KB
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../home/widgets/today/today_faq_bottom_sheet.dart';

void showRefundExplanationBottomSheet() {
  Get.bottomSheet(
    DraggableScrollableSheet(
      initialChildSize: 0.936,
      minChildSize: 0.2,
      maxChildSize: 0.936,
      expand: false,
      snap: true,
      builder: (context, scrollController) => RefundExplanationBottomSheet(
        scrollController: scrollController,
      ),
    ),
    barrierColor: Colors.black.withValues(alpha: 0.7),
    enableDrag: true,
    isScrollControlled: true,
    persistent: false,
  );
}

class RefundExplanationBottomSheet extends StatelessWidget {
  const RefundExplanationBottomSheet({
    super.key,
    required this.scrollController,
  });

  final ScrollController scrollController;

  @override
  Widget build(BuildContext context) {
    final l10n = context.l10n;

    return Container(
      decoration: const BoxDecoration(
        color: Color(0xFFF5F2FF),
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      child: SafeArea(
        top: false,
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              height: 64,
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Text(
                    l10n.refundExplanationTitle,
                    style: TextStyle(
                      color: context.colors.textPrimary,
                      fontSize: 16,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  Positioned(
                    left: 16,
                    top: 10,
                    child: GestureDetector(
                      behavior: HitTestBehavior.opaque,
                      onTap: Get.back,
                      child: SizedBox(
                        width: 44,
                        height: 44,
                        child: Center(
                          child: Image.asset(
                            'assets/images/common/ic_close.png',
                            width: 20,
                            height: 20,
                            color: context.colors.chartPurple,
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Expanded(
              child: ListView(
                controller: scrollController,
                physics: const ClampingScrollPhysics(),
                padding: const EdgeInsets.fromLTRB(16, 0, 16, 20),
                children: [
                  _InfoCard(
                    title: l10n.refundAppStoreReviewTitle,
                    lines: [
                      _InfoLine(l10n.refundAppStoreReviewDescription),
                      _InfoLine(l10n.refundAppleRulesIntroduction),
                      _InfoLine(l10n.refundAppleCollectsPayments),
                      _InfoLine(l10n.refundAppleReviewsRequests),
                      _InfoLine(l10n.refundDeveloperCannotSubmit),
                      _InfoLine(l10n.refundDeveloperCannotIntervene),
                      _InfoLine(l10n.refundAppStoreFinalDecision,
                          warning: true),
                    ],
                  ),
                  const SizedBox(height: 12),
                  _InfoCard(
                    title: l10n.refundMayBeRejectedTitle,
                    lines: [
                      _InfoLine(l10n.refundNoUnconditionalRefunds,
                          warning: true),
                      _InfoLine(l10n.refundAppleTermsDescription),
                      _InfoLine(l10n.refundAppleReviewsCircumstances,
                          warning: true),
                    ],
                  ),
                  const SizedBox(height: 12),
                  _InfoCard(
                    title: l10n.refundRejectionReasonsTitle,
                    lines: [
                      _InfoLine(l10n.refundRejectionReasonsIntroduction),
                      _InfoLine(l10n.refundReasonPurchaseTooOld, warning: true),
                      _InfoLine(l10n.refundReasonFrequentRequests,
                          warning: true),
                      _InfoLine(l10n.refundReasonAbnormalHistory,
                          warning: true),
                      _InfoLine(l10n.refundReasonInsufficient, warning: true),
                      _InfoLine(l10n.refundReasonLongTermUse, warning: true),
                      _InfoLine(l10n.refundReasonPriceChange, warning: true),
                      _InfoLine(l10n.refundReasonNoReceipt, warning: true),
                      _InfoLine(l10n.refundOfficialDecision),
                    ],
                  ),
                  const SizedBox(height: 12),
                  _InfoCard(
                    title: l10n.refundRejectedNextStepsTitle,
                    lines: [
                      _InfoLine(l10n.refundTryAgain),
                      _InfoLine(l10n.refundFinalReview, warning: true),
                      _InfoLine(l10n.refundNoAlternativeChannel, warning: true),
                      _InfoLine(l10n.refundMembershipCancellation),
                    ],
                  ),
                  const SizedBox(height: 12),
                  _InfoCard(
                    title: l10n.refundHelpTitle,
                    lines: [_InfoLine(l10n.refundHelpDescription)],
                  ),
                  const SizedBox(height: 12),
                  const _FaqLinksCard(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _InfoCard extends StatelessWidget {
  const _InfoCard({
    required this.title,
    required this.lines,
    this.child,
  });

  final String title;
  final List<_InfoLine> lines;
  final Widget? child;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            title,
            style: TextStyle(
              color: context.colors.textPrimary,
              fontSize: 12,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(height: 12),
          if (child != null)
            child!
          else
            Text.rich(
              TextSpan(
                children: [
                  for (var index = 0; index < lines.length; index++)
                    TextSpan(
                      text:
                          '${lines[index].text}${index == lines.length - 1 ? '' : '\n'}',
                      style: TextStyle(
                        color: lines[index].warning
                            ? const Color(0xFFFC4447)
                            : context.colors.textSecondary,
                      ),
                    ),
                ],
              ),
              style: const TextStyle(
                fontSize: 12,
                height: 17 / 12,
                fontWeight: FontWeight.w400,
              ),
            ),
        ],
      ),
    );
  }
}

class _InfoLine {
  const _InfoLine(this.text, {this.warning = false});

  final String text;
  final bool warning;
}

class _FaqLinksCard extends StatelessWidget {
  const _FaqLinksCard();

  @override
  Widget build(BuildContext context) {
    final l10n = context.l10n;

    return _InfoCard(
      title: l10n.refundFaqTitle,
      lines: const [],
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _FaqLink(l10n.todayFaqLinkNoData),
          _FaqLink(l10n.todayFaqLinkHrvRealtimeUpdate),
          _FaqLink(l10n.todayFaqLinkWatchNoStatusAndInteractionNotification),
          _FaqLink(l10n.todayFaqLinkWatchFaceDataDelay),
          _FaqLink(l10n.todayFaqLinkWatchFaceBlackScreen, bottomSpacing: 0),
        ],
      ),
    );
  }
}

class _FaqLink extends StatelessWidget {
  const _FaqLink(this.text, {this.bottomSpacing = 14});

  final String text;
  final double bottomSpacing;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: showTodayFaqBottomSheet,
      child: Padding(
        padding: EdgeInsets.only(bottom: bottomSpacing),
        child: Text(
          text,
          style: TextStyle(
            color: context.colors.textSecondary,
            fontSize: 12,
            height: 17 / 12,
            decoration: TextDecoration.underline,
          ),
        ),
      ),
    );
  }
}