import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../api/api_client_provider.dart';

part 'chat_opening_provider.g.dart';

class PriceTier {
  final int durationMinutes;
  final int price;
  final String label;
  final String? id;
  final String? tag;

  const PriceTier({
    required this.durationMinutes,
    required this.price,
    required this.label,
    this.id,
    this.tag,
  });

  /// Phase 4 shape: `{ id, minutes, price_idr, tag }` — used by the new
  /// chat/call tier groups. Falls back to the legacy free-trial-pricing shape
  /// (`{ duration_minutes, price, label }`) for back-compat with the Phase 3
  /// `/api/client/chat/pricing` payload still consumed by the legacy payment
  /// screen + bottom sheet.
  factory PriceTier.fromJson(Map<String, dynamic> json) {
    final minutes = (json['minutes'] ?? json['duration_minutes']) as int;
    final price = (json['price_idr'] ?? json['price']) as int;
    final label = (json['label'] as String?) ?? '$minutes Menit';
    return PriceTier(
      durationMinutes: minutes,
      price: price,
      label: label,
      id: (json['id'] as String?) ?? minutes.toString(),
      tag: json['tag'] as String?,
    );
  }
}

/// First-session discount block. Mirrors backend
/// `pricing.first_session_discount`. Server-authoritative — the client only
/// reads this; the actual discount price is re-validated on the backend when
/// the payment session is created.
class FirstSessionDiscount {
  final bool eligible;
  final int actualPriceIDR;
  final int gimmickPriceIDR;
  final int durationMinutes;
  final List<String> modes;

  const FirstSessionDiscount({
    required this.eligible,
    required this.actualPriceIDR,
    required this.gimmickPriceIDR,
    required this.durationMinutes,
    required this.modes,
  });

  factory FirstSessionDiscount.fromJson(Map<String, dynamic> json) {
    final modesRaw = json['modes'];
    final modes = modesRaw is List
        ? modesRaw.map((e) => e.toString()).toList()
        : const <String>['chat'];
    return FirstSessionDiscount(
      eligible: json['eligible'] as bool? ?? false,
      actualPriceIDR: json['actual_price_idr'] as int? ?? 0,
      gimmickPriceIDR: json['gimmick_price_idr'] as int? ?? 0,
      durationMinutes: json['duration_minutes'] as int? ?? 0,
      modes: modes,
    );
  }
}

class PricingData {
  /// Legacy single-list tiers. Populated from `data.tiers` when the response
  /// uses the Phase 3 shape; populated from `data.chat.tiers` when the
  /// Phase 4 shape is returned (so existing callers keep working).
  final List<PriceTier> tiers;
  final bool freeTrialEligible;
  final int freeTrialDurationMinutes;

  /// Phase 4 chat-mode tiers (`pricing.chat.tiers`). Empty when the backend
  /// still returns the Phase 3 shape.
  final List<PriceTier> chatTiers;

  /// Phase 4 call-mode tiers (`pricing.call.tiers`). Empty when the backend
  /// still returns the Phase 3 shape.
  final List<PriceTier> callTiers;

  /// Phase 4 first-session discount block. Null when the backend still
  /// returns the Phase 3 shape.
  final FirstSessionDiscount? firstSessionDiscount;

  const PricingData({
    required this.tiers,
    required this.freeTrialEligible,
    this.freeTrialDurationMinutes = 5,
    this.chatTiers = const [],
    this.callTiers = const [],
    this.firstSessionDiscount,
  });
}

@riverpod
Future<PricingData> chatPricing(Ref ref) async {
  final apiClient = ref.read(apiClientProvider);
  final response = await apiClient.get('/api/client/chat/pricing');
  final data = response['data'] as Map<String, dynamic>;

  // Phase 4 shape — `data.chat.tiers` + `data.call.tiers` + `first_session_discount`.
  // Phase 3 shape — `data.tiers` + `data.free_trial`. Detect which we got and
  // populate the model accordingly.
  final hasPhase4Groups = data['chat'] is Map<String, dynamic>;

  if (hasPhase4Groups) {
    final chat = data['chat'] as Map<String, dynamic>;
    final call = (data['call'] as Map<String, dynamic>?) ?? const {};
    final chatTiers = (chat['tiers'] as List<dynamic>? ?? const [])
        .map((t) => PriceTier.fromJson(t as Map<String, dynamic>))
        .toList();
    final callTiers = (call['tiers'] as List<dynamic>? ?? const [])
        .map((t) => PriceTier.fromJson(t as Map<String, dynamic>))
        .toList();
    final discountJson = data['first_session_discount'] as Map<String, dynamic>?;
    final discount = discountJson != null ? FirstSessionDiscount.fromJson(discountJson) : null;
    return PricingData(
      tiers: chatTiers,
      freeTrialEligible: false,
      chatTiers: chatTiers,
      callTiers: callTiers,
      firstSessionDiscount: discount,
    );
  }

  final tiersJson = data['tiers'] as List<dynamic>;
  final tiers = tiersJson.map((t) => PriceTier.fromJson(t as Map<String, dynamic>)).toList();
  final freeTrial = (data['free_trial'] as Map<String, dynamic>?) ?? const {};

  return PricingData(
    tiers: tiers,
    freeTrialEligible: freeTrial['eligible'] as bool? ?? false,
    freeTrialDurationMinutes: freeTrial['duration_minutes'] as int? ?? 5,
  );
}
