import 'package:flutter/foundation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../../../core/constants.dart';

part 'payment_draft_provider.g.dart';

/// Session mode the customer is paying for. Mirrors backend `SessionMode`
/// (chat | call). Phase 4 introduces `call` as a future option — pricing config
/// supplies the call tier list, but no functional voice feature is built yet.
enum PaymentMode {
  chat('chat'),
  call('call');

  final String value;
  const PaymentMode(this.value);

  static PaymentMode fromString(String? v) =>
      values.firstWhere((e) => e.value == v, orElse: () => PaymentMode.chat);
}

/// Draft state shared across the multi-screen payment flow:
/// discount-paywall / method-pick / duration-pick / method / waiting / expired.
///
/// The state is deliberately minimal — the *source of truth* for amount and
/// duration is always the backend (server-validated tier or first-session
/// discount). The draft only carries the customer's in-flight intent across
/// the screen graph.
class PaymentDraft {
  final PaymentMode mode;
  final String? durationId;
  final int? durationMinutes;
  final int? priceIDR;
  final String? paymentId;
  final bool isFirstSessionDiscount;

  /// When set, this payment is for a "Curhat lagi" (returning-targeted) flow:
  /// downstream of payment confirm, `searching_screen` will fire the targeted
  /// chat request against this specific mitra rather than the general blast.
  /// Set by `BestieHistoryListScreen` BEFORE pushing `/payment/entry`.
  final String? targetedMitraId;

  /// Optional display name for the targeted mitra — surfaced on the targeted
  /// waiting overlay ("lagi nungguin {name}") and any future returning-flow UI
  /// that wants to greet the customer with the right bestie.
  final String? targetedMitraName;

  /// Topic-sensitivity choice made before entering the payment flow. Carried
  /// through to the eventual chat-request API call. Defaults to `regular`.
  final TopicSensitivity topicSensitivity;

  const PaymentDraft({
    this.mode = PaymentMode.chat,
    this.durationId,
    this.durationMinutes,
    this.priceIDR,
    this.paymentId,
    this.isFirstSessionDiscount = false,
    this.targetedMitraId,
    this.targetedMitraName,
    this.topicSensitivity = TopicSensitivity.regular,
  });

  PaymentDraft copyWith({
    PaymentMode? mode,
    String? durationId,
    int? durationMinutes,
    int? priceIDR,
    String? paymentId,
    bool? isFirstSessionDiscount,
    String? targetedMitraId,
    String? targetedMitraName,
    TopicSensitivity? topicSensitivity,
  }) {
    return PaymentDraft(
      mode: mode ?? this.mode,
      durationId: durationId ?? this.durationId,
      durationMinutes: durationMinutes ?? this.durationMinutes,
      priceIDR: priceIDR ?? this.priceIDR,
      paymentId: paymentId ?? this.paymentId,
      isFirstSessionDiscount: isFirstSessionDiscount ?? this.isFirstSessionDiscount,
      targetedMitraId: targetedMitraId ?? this.targetedMitraId,
      targetedMitraName: targetedMitraName ?? this.targetedMitraName,
      topicSensitivity: topicSensitivity ?? this.topicSensitivity,
    );
  }
}

@Riverpod(keepAlive: true)
class PaymentDraftNotifier extends _$PaymentDraftNotifier {
  @override
  PaymentDraft build() => const PaymentDraft();

  void setMode(PaymentMode mode) {
    // Switching mode resets the previously-picked tier — chat and call
    // tier lists are independent.
    state = state.copyWith(
      mode: mode,
      durationId: null,
      durationMinutes: null,
      priceIDR: null,
    );
  }

  void setTier({
    required String durationId,
    required int durationMinutes,
    required int priceIDR,
  }) {
    state = state.copyWith(
      durationId: durationId,
      durationMinutes: durationMinutes,
      priceIDR: priceIDR,
    );
  }

  void setDiscountPlan({
    required int durationMinutes,
    required int priceIDR,
  }) {
    state = state.copyWith(
      mode: PaymentMode.chat,
      durationMinutes: durationMinutes,
      priceIDR: priceIDR,
      isFirstSessionDiscount: true,
    );
  }

  void setPaymentId(String paymentId) {
    state = state.copyWith(paymentId: paymentId);
  }

  /// Mark this draft as a targeted "Curhat lagi" flow against a specific
  /// mitra. Must be called BEFORE pushing `/payment/entry` from the
  /// bestie-history list — the entry screen calls [resetExceptTarget] to
  /// clear stale tier/payment state while preserving the targeting set here.
  void setTargetedMitra({required String mitraId, String? mitraName}) {
    state = state.copyWith(
      targetedMitraId: mitraId,
      targetedMitraName: mitraName,
    );
  }

  /// Set the topic-sensitivity choice for the upcoming chat request.
  void setTopicSensitivity(TopicSensitivity topicSensitivity) {
    state = state.copyWith(topicSensitivity: topicSensitivity);
  }

  /// Full reset — clears EVERYTHING including targeted-mitra intent.
  /// Use this when starting a fresh BLAST flow (e.g. "bestie baru" branch or
  /// the no-history Home CTA). If you want to preserve a targeted-mitra
  /// selection made just before entering the payment flow (set via
  /// [setTargetedMitra]), use [resetExceptTarget] instead.
  void reset() {
    debugPrint('[PaymentDraft] reset() — clearing entire draft including targeted-mitra intent');
    state = const PaymentDraft();
  }

  /// Reset everything EXCEPT the targeted-mitra fields. Used by the payment
  /// entry screen so a fresh dive into the multi-screen flow clears any stale
  /// tier/payment state while preserving the just-picked targeted mitra. If
  /// the draft has no targeted mitra set, this behaves identically to
  /// [reset].
  void resetExceptTarget() {
    debugPrint(
      '[PaymentDraft] resetExceptTarget() — preserving targetedMitraId=${state.targetedMitraId}',
    );
    state = PaymentDraft(
      targetedMitraId: state.targetedMitraId,
      targetedMitraName: state.targetedMitraName,
      topicSensitivity: state.topicSensitivity,
    );
  }
}
