import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/chat/chat_opening_provider.dart';
import '../../../core/constants.dart';
import '../../../core/pairing/pairing_notifier.dart';
import '../payment_notifier.dart';

/// Payment screen.
///
/// Reuses the mock pricing service (tiers + free trial). The customer picks a
/// duration (or auto-selects the free trial); on tap the screen creates a
/// `pending` payment session, then on "Bayar" / "Mulai" confirms it and routes
/// to the searching screen carrying `paymentSessionId` (and `targetedMitraId`
/// if this is a "Curhat lagi" flow).
///
/// Reachable from:
///   - Home "Mulai Curhat" CTA  → no targeted mitra, normal blast follows.
///   - Chat history "Curhat lagi" CTA → targetedMitraId set, returning-chat
///     flow follows.
class PaymentScreen extends ConsumerStatefulWidget {
  /// "Curhat lagi" only — when set, the eventual chat-request goes through
  /// the returning-chat endpoint targeting this mitra.
  final String? targetedMitraId;

  /// Optional display name for the targeted mitra, surfaced in the screen
  /// header so the customer knows who they're paying to chat with again.
  final String? mitraName;

  /// The topic-sensitivity choice the customer made in the topic-selection
  /// bottom sheet on the home screen. Carried through here to be passed into
  /// the chat-request API after confirm. Defaults to regular.
  final TopicSensitivity topicSensitivity;

  const PaymentScreen({
    super.key,
    this.targetedMitraId,
    this.mitraName,
    this.topicSensitivity = TopicSensitivity.regular,
  });

  @override
  ConsumerState<PaymentScreen> createState() => _PaymentScreenState();
}

class _PaymentScreenState extends ConsumerState<PaymentScreen> {
  /// Local UI selection (not in the notifier) — the duration the customer is
  /// previewing before they tap to lock it in via createSession.
  int? _selectedDurationMinutes;

  /// True once we've kicked off `createSession()` for the current selection;
  /// used to suppress double-taps while the round-trip is in flight.
  bool _creatingSession = false;

  @override
  void initState() {
    super.initState();
    // Make sure no stale state leaks in from a previous payment attempt.
    Future.microtask(() => ref.read(paymentProvider.notifier).reset());
  }

  @override
  void dispose() {
    // Best-effort cancel on back/dispose if we still have a `pending` row.
    // The notifier checks state before calling the API, so this is safe to
    // call unconditionally.
    // ignore: discarded_futures
    ref.read(paymentProvider.notifier).cancelIfPending();
    super.dispose();
  }


  Future<void> _onTierTapped({
    required int durationMinutes,
    required int price,
  }) async {
    if (_creatingSession) return;
    // `price` is informational (already shown in the tier card) — the source
    // of truth for the amount comes back from the backend.
    setState(() {
      _selectedDurationMinutes = durationMinutes;
      _creatingSession = true;
    });
    await ref.read(paymentProvider.notifier).createSession(
          durationMinutes: durationMinutes,
          targetedMitraId: widget.targetedMitraId,
        );
    if (mounted) setState(() => _creatingSession = false);
  }

  Future<void> _onConfirmTapped() async {
    final notifier = ref.read(paymentProvider.notifier);
    await notifier.confirm();
  }

  Future<void> _routeToSearchOnConfirmed(PaymentConfirmedData payment) async {
    // Kick off the right pairing flow against the freshly-confirmed payment.
    final pairing = ref.read(pairingProvider.notifier);
    if (payment.targetedMitraId != null) {
      await pairing.startTargetedSearch(
        paymentSessionId: payment.paymentSessionId,
        mitraId: payment.targetedMitraId!,
        mitraName: widget.mitraName ?? 'Bestie',
        topicSensitivity: widget.topicSensitivity,
      );
    } else {
      await pairing.startSearch(
        paymentSessionId: payment.paymentSessionId,
        topicSensitivity: widget.topicSensitivity,
      );
    }
    if (!mounted) return;
    // Reset our local notifier so a future payment attempt starts clean.
    ref.read(paymentProvider.notifier).reset();
    // Phase 4 Stage 5: targeted "Curhat lagi" lands on the dedicated
    // SWaitingBestie overlay screen; general blast still uses the searching
    // shell (which renders inline soft-prompt + timeout panels).
    if (payment.targetedMitraId != null) {
      context.go('/chat/waiting-targeted/${payment.targetedMitraId}');
    } else {
      context.go('/chat/searching');
    }
  }

  @override
  Widget build(BuildContext context) {
    // One-shot side-effect listener: when the payment lands in `confirmed`,
    // route to the searching screen.
    ref.listen<PaymentSessionData>(paymentProvider, (prev, next) {
      if (next is PaymentConfirmedData) {
        // ignore: discarded_futures
        _routeToSearchOnConfirmed(next);
      }
    });

    final paymentState = ref.watch(paymentProvider);
    final pricingAsync = ref.watch(chatPricingProvider);
    final isReturning = widget.targetedMitraId != null;

    return PopScope(
      canPop: true,
      child: Scaffold(
        appBar: AppBar(
          title: Text(isReturning ? 'Chat lagi dengan ${widget.mitraName ?? 'Bestie'}' : 'Pilih Sesi & Bayar'),
          leading: IconButton(
            icon: const Icon(Icons.chevron_left),
            onPressed: () {
              // PopScope above lets canPop fire dispose() which cancels the
              // pending session. If there's no back-stack, fall back to home.
              if (context.canPop()) {
                context.pop();
              } else {
                context.go('/home');
              }
            },
          ),
        ),
        body: pricingAsync.when(
          loading: () => const Center(child: CircularProgressIndicator()),
          error: (_, __) => const Center(
            child: Padding(
              padding: EdgeInsets.all(24),
              child: Text('Gagal memuat harga. Coba lagi.', textAlign: TextAlign.center),
            ),
          ),
          data: (pricing) => _buildBody(pricing, paymentState),
        ),
      ),
    );
  }

  Widget _buildBody(PricingData pricing, PaymentSessionData paymentState) {
    // Inline error widget per project memory ("Avoid SnackBars for provider errors").
    final errorBanner = paymentState is PaymentErrorData
        ? Container(
            margin: const EdgeInsets.fromLTRB(16, 16, 16, 0),
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: Colors.red.shade50,
              borderRadius: BorderRadius.circular(8),
              border: Border.all(color: Colors.red.shade200),
            ),
            child: Row(
              children: [
                Icon(Icons.error_outline, color: Colors.red.shade700),
                const SizedBox(width: 8),
                Expanded(
                  child: Text(
                    paymentState.message,
                    style: TextStyle(color: Colors.red.shade900),
                  ),
                ),
              ],
            ),
          )
        : const SizedBox.shrink();

    return Column(
      children: [
        errorBanner,
        Expanded(
          child: ListView(
            padding: const EdgeInsets.all(24),
            children: [
              const Text(
                'Pilih Durasi Curhat',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 16),
              if (pricing.freeTrialEligible) ...[
                _FreeTrialCard(
                  durationMinutes: pricing.freeTrialDurationMinutes,
                  selected: paymentState is PaymentPendingData && paymentState.isFreeTrial,
                  onTap: () => _onTierTapped(
                    // For free trial: backend still wants a duration_minutes —
                    // pass the trial duration. The backend overrides amount→0
                    // when the customer is eligible.
                    durationMinutes: pricing.freeTrialDurationMinutes,
                    price: 0,
                  ),
                ),
                const Divider(height: 24),
              ],
              ...pricing.tiers.map((tier) {
                final selected = _selectedDurationMinutes == tier.durationMinutes &&
                    paymentState is PaymentPendingData &&
                    !paymentState.isFreeTrial;
                return _TierCard(
                  label: tier.label,
                  priceLabel: formatRupiah(tier.price),
                  selected: selected,
                  onTap: () => _onTierTapped(
                    durationMinutes: tier.durationMinutes,
                    price: tier.price,
                  ),
                );
              }),
            ],
          ),
        ),
        if (paymentState is PaymentPendingData ||
            paymentState is PaymentConfirmingData ||
            paymentState is PaymentCreatingData)
          _ConfirmBar(
            paymentState: paymentState,
            onConfirm: _onConfirmTapped,
            formatPrice: formatRupiah,
          ),
      ],
    );
  }
}

class _FreeTrialCard extends StatelessWidget {
  final int durationMinutes;
  final bool selected;
  final VoidCallback onTap;

  const _FreeTrialCard({
    required this.durationMinutes,
    required this.selected,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      color: selected ? Colors.green.shade100 : Colors.green.shade50,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(12),
        side: selected
            ? BorderSide(color: Colors.green.shade700, width: 1.5)
            : BorderSide.none,
      ),
      child: ListTile(
        leading: const Icon(Icons.card_giftcard, color: Colors.green),
        title: Text('Free Trial ($durationMinutes Menit)'),
        subtitle: const Text('Gratis untuk pertama kali!'),
        trailing: Text(
          'Gratis',
          style: TextStyle(fontWeight: FontWeight.bold, color: Colors.green.shade800),
        ),
        onTap: onTap,
      ),
    );
  }
}

class _TierCard extends StatelessWidget {
  final String label;
  final String priceLabel;
  final bool selected;
  final VoidCallback onTap;

  const _TierCard({
    required this.label,
    required this.priceLabel,
    required this.selected,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(12),
        side: selected
            ? const BorderSide(color: Colors.pink, width: 1.5)
            : BorderSide.none,
      ),
      child: ListTile(
        title: Text(label),
        trailing: Text(
          priceLabel,
          style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
        ),
        onTap: onTap,
      ),
    );
  }
}

class _ConfirmBar extends StatelessWidget {
  final PaymentSessionData paymentState;
  final Future<void> Function() onConfirm;
  final String Function(int) formatPrice;

  const _ConfirmBar({
    required this.paymentState,
    required this.onConfirm,
    required this.formatPrice,
  });

  @override
  Widget build(BuildContext context) {
    final isCreating = paymentState is PaymentCreatingData;
    final isConfirming = paymentState is PaymentConfirmingData;
    final pending = paymentState is PaymentPendingData ? paymentState as PaymentPendingData : null;

    final totalLabel = pending == null
        ? '...'
        : pending.isFreeTrial
            ? 'Gratis'
            : formatPrice(pending.amount);
    final ctaLabel = pending != null && pending.isFreeTrial ? 'Mulai' : 'Bayar';
    final disabled = isCreating || isConfirming || pending == null;

    return SafeArea(
      top: false,
      child: Container(
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [
            BoxShadow(
              color: Colors.black.withValues(alpha: 0.04),
              blurRadius: 8,
              offset: const Offset(0, -2),
            ),
          ],
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text('Total', style: TextStyle(fontSize: 16)),
                Text(
                  totalLabel,
                  style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
              ],
            ),
            const SizedBox(height: 12),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(vertical: 14),
                ),
                onPressed: disabled ? null : onConfirm,
                child: isConfirming || isCreating
                    ? const SizedBox(
                        width: 20,
                        height: 20,
                        child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
                      )
                    : Text(ctaLabel, style: const TextStyle(fontSize: 16)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
