// lib/features/booking/providers/checkout_provider.dart

import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/api/api_endpoints.dart';
import '../../../core/utils/error_utils.dart';
import '../models/booking_models.dart';
import '../services/booking_service.dart';

enum CheckoutStep { tickets, details, payment, confirmation }

class CheckoutProvider extends ChangeNotifier {
  final BookingService _service = BookingService();

  // Event being booked
  int? eventId;
  String eventName = '';

  // Step tracking
  CheckoutStep currentStep = CheckoutStep.tickets;

  // Ticket selection
  List<TicketMetaModel> availableTickets = [];
  List<CartItemModel> cart = [];

  // Shipping
  ShippingDetails? shippingDetails;

  // Coupon / promo
  String? couponCode;
  double discountAmount = 0.0;
  String? promoMessage;
  bool promoApplied = false;

  // Status
  bool loading = false;
  String? error;
  String? paymentId;

  /// Initialize checkout for an event.
  Future<void> initForEvent(int eventId, String eventName) async {
    this.eventId = eventId;
    this.eventName = eventName;
    currentStep = CheckoutStep.tickets;
    cart = [];
    shippingDetails = null;
    couponCode = null;
    discountAmount = 0.0;
    promoMessage = null;
    promoApplied = false;
    paymentId = null;
    error = null;
    loading = true;
    notifyListeners();

    try {
      availableTickets = await _service.getTicketMeta(eventId);
    } catch (e) {
      error = userFriendlyError(e);
    } finally {
      loading = false;
      notifyListeners();
    }
  }

  /// Add or update cart item.
  void setTicketQuantity(TicketMetaModel ticket, int qty) {
    cart.removeWhere((c) => c.ticket.id == ticket.id);
    if (qty > 0) {
      cart.add(CartItemModel(ticket: ticket, quantity: qty));
    }
    notifyListeners();
  }

  double get subtotal => cart.fold(0, (sum, item) => sum + item.subtotal);
  double get total => subtotal - discountAmount;

  bool get hasItems => cart.isNotEmpty;

  /// Move to next step.
  void nextStep() {
    if (currentStep == CheckoutStep.tickets && hasItems) {
      currentStep = CheckoutStep.details;
    } else if (currentStep == CheckoutStep.details && shippingDetails != null) {
      currentStep = CheckoutStep.payment;
    }
    notifyListeners();
  }

  /// Move to previous step.
  void previousStep() {
    if (currentStep == CheckoutStep.payment) {
      currentStep = CheckoutStep.details;
    } else if (currentStep == CheckoutStep.details) {
      currentStep = CheckoutStep.tickets;
    }
    notifyListeners();
  }

  /// Set shipping details from form.
  void setShipping(ShippingDetails details) {
    shippingDetails = details;
    notifyListeners();
  }

  /// Apply a promo code against the backend.
  Future<bool> applyPromo(String code) async {
    if (code.trim().isEmpty) return false;
    loading = true;
    error = null;
    notifyListeners();
    try {
      final prefs = await SharedPreferences.getInstance();
      final token = prefs.getString('access_token') ?? '';
      final response = await http.post(
        Uri.parse('${ApiEndpoints.baseUrl}/bookings/apply-promo/'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $token',
        },
        body: jsonEncode({'code': code.trim(), 'event_id': eventId}),
      );
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        if (data['valid'] == true) {
          discountAmount = (data['discount_amount'] as num?)?.toDouble() ?? 0.0;
          couponCode = code.trim();
          promoMessage = data['message'] as String? ?? 'Promo applied!';
          promoApplied = true;
          notifyListeners();
          return true;
        } else {
          promoMessage = data['message'] as String? ?? 'Invalid promo code';
          promoApplied = false;
          discountAmount = 0.0;
          couponCode = null;
          notifyListeners();
          return false;
        }
      } else {
        promoMessage = 'Could not apply promo code';
        return false;
      }
    } catch (e) {
      promoMessage = 'Could not apply promo code';
      return false;
    } finally {
      loading = false;
      notifyListeners();
    }
  }

  /// Remove applied promo code.
  void resetPromo() {
    discountAmount = 0.0;
    couponCode = null;
    promoMessage = null;
    promoApplied = false;
    notifyListeners();
  }

  /// Process checkout on backend.
  Future<Map<String, dynamic>> processCheckout() async {
    loading = true;
    error = null;
    notifyListeners();

    try {
      final tickets = cart.map((c) => {
        'ticket_meta_id': c.ticket.id,
        'quantity': c.quantity,
      }).toList();

      final res = await _service.processCheckout(
        eventId: eventId!,
        tickets: tickets,
        shippingDetails: shippingDetails?.toJson() ?? {},
        couponCode: couponCode,
      );
      return res;
    } catch (e) {
      error = userFriendlyError(e);
      rethrow;
    } finally {
      loading = false;
      notifyListeners();
    }
  }

  /// Mark payment as complete.
  void markPaymentSuccess(String id) {
    paymentId = id;
    currentStep = CheckoutStep.confirmation;
    notifyListeners();
  }

  /// Reset checkout state.
  void reset() {
    eventId = null;
    eventName = '';
    currentStep = CheckoutStep.tickets;
    availableTickets = [];
    cart = [];
    shippingDetails = null;
    couponCode = null;
    discountAmount = 0.0;
    promoMessage = null;
    promoApplied = false;
    paymentId = null;
    error = null;
    loading = false;
    notifyListeners();
  }
}
