import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:razorpay_flutter/razorpay_flutter.dart';
import 'package:upi_india/upi_india.dart';
import 'package:bookatanker/common/settings.dart';

class CreditTopUpConfirmScreen extends StatefulWidget {
  final String supplierName;
  final String supplierId;

  const CreditTopUpConfirmScreen({
    super.key,
    required this.supplierName,
    required this.supplierId,
  });

  @override
  State<CreditTopUpConfirmScreen> createState() => _CreditTopUpConfirmScreenState();
}

class _CreditTopUpConfirmScreenState extends State<CreditTopUpConfirmScreen> {
  final TextEditingController amountCtrl = TextEditingController(text: "2000");
  bool isPaying = false;
  String? errorText;

  // UPI
  late UpiIndia _upiIndia;
  List<UpiApp> _apps = [];
  UpiApp? _selectedUpiApp;

  // Razorpay
  Razorpay? _razorpay;

  @override
  void initState() {
    super.initState();
    _upiIndia = UpiIndia();
    _loadUpiApps();

    _razorpay = Razorpay();
    _razorpay!.on(Razorpay.EVENT_PAYMENT_SUCCESS, _onRazorpaySuccess);
    _razorpay!.on(Razorpay.EVENT_PAYMENT_ERROR, _onRazorpayError);
    _razorpay!.on(Razorpay.EVENT_EXTERNAL_WALLET, _onRazorpayExternalWallet);
  }

  @override
  void dispose() {
    amountCtrl.dispose();
    _razorpay?.clear();
    super.dispose();
  }

  Future<void> _loadUpiApps() async {
    try {
      final apps = await _upiIndia.getAllUpiApps(mandatoryTransactionId: false);
      if (!mounted) return;
      setState(() {
        _apps = apps;
        // Prefer PhonePe if exists else first
        _selectedUpiApp = _apps.firstWhere(
              (a) => a.name.toLowerCase().contains("phonepe"),
          orElse: () => _apps.isNotEmpty ? _apps.first : UpiApp.bhim,
        );
      });
    } catch (_) {
      // Ignore, we will show Razorpay option anyway
    }
  }

  double _readAmount() {
    final raw = amountCtrl.text.trim().replaceAll(",", "");
    final v = double.tryParse(raw) ?? 0;
    return v;
  }

  bool _validateAmount() {
    final amt = _readAmount();
    if (amt < 1) {
      setState(() => errorText = "Enter a valid amount");
      return false;
    }
    if (amt > 1000000) {
      setState(() => errorText = "Amount too high");
      return false;
    }
    setState(() => errorText = null);
    return true;
  }

  Future<void> _payViaSelectedUpiApp() async {
    if (!_validateAmount()) return;
    if (_selectedUpiApp == null) {
      setState(() => errorText = "No UPI app found. Use Razorpay option.");
      return;
    }

    final amt = _readAmount();

    setState(() {
      isPaying = true;
      errorText = null;
    });

    try {
      // 🔥 Use YOUR business UPI ID here (store / supplier / platform UPI)
      // If you want supplier-wise UPI ID, pass it in widget.
      const receiverUpiId = "9912686262@xyz";
      const receiverName = "Water Management";

      final txnRef = "TOPUP_${DateTime.now().millisecondsSinceEpoch}";

      final res = await _upiIndia.startTransaction(
        app: _selectedUpiApp!,
        receiverUpiId: receiverUpiId,
        receiverName: receiverName,
        transactionRefId: txnRef,
        transactionNote: "Credit TopUp",
        amount: amt,
      );

      if (!mounted) return;

      // ✅ UPI result handling
      final status = (res.status ?? "").toLowerCase();
      if (status == UpiPaymentStatus.SUCCESS.toLowerCase()) {
        // Save in your backend
        await AppSettings.addAdvanceTopUp(
          widget.supplierId,
          AppSettings.customerId,
          amt,
          "upi_${_selectedUpiApp!.name.toLowerCase()}",
          gatewayTxnId: res.transactionId ?? txnRef,
        );

        if (!mounted) return;
        Navigator.pop(context, true);
      } else if (status == UpiPaymentStatus.SUBMITTED.toLowerCase()) {
        setState(() => errorText = "Payment pending. Please check in your UPI app.");
      } else {
        setState(() => errorText = "Payment failed or cancelled.");
      }
    } catch (e) {
      if (!mounted) return;
      setState(() => errorText = "Payment failed. Try again.");
    } finally {
      if (mounted) setState(() => isPaying = false);
    }
  }

  /// ✅ Razorpay (Recommended for full PhonePe/cards/netbanking etc.)
  /// Backend creates order_id securely, then open checkout.
  Future<void> _payViaRazorpay() async {
    if (!_validateAmount()) return;

    final amt = _readAmount();

    setState(() {
      isPaying = true;
      errorText = null;
    });

    try {
      // 1) Create Razorpay order from backend
      final orderResp = await AppSettings.createRazorpayOrder(
        amount: amt,
        supplierId: widget.supplierId,
        customerId: AppSettings.customerId,
      );

      final decoded = jsonDecode(orderResp);
      final orderId = decoded["order_id"]; // backend should return this
      final keyId = decoded["key_id"];     // backend may return key_id or keep static in app

      if (orderId == null || keyId == null) {
        throw Exception("Invalid order response");
      }

      final options = {
        'key': keyId,
        'amount': (amt * 100).round(), // paise
        'name': widget.supplierName,
        'description': 'Credit Top Up',
        'order_id': orderId,
        'retry': {'enabled': true, 'max_count': 1},
        'prefill': {
          'contact': AppSettings.phoneNumber ?? '',
          'email': AppSettings.email ?? '',
        },
        'theme': {'color': '#1D7AFC'},
        // 'external': {'wallets': ['paytm']} // optional
      };

      _razorpay?.open(options);
    } catch (e) {
      if (!mounted) return;
      setState(() {
        isPaying = false;
        errorText = "Unable to start payment. Try again.";
      });
    }
  }

  // Razorpay callbacks
  Future<void> _onRazorpaySuccess(PaymentSuccessResponse response) async {
    final amt = _readAmount();

    try {
      // 2) Verify payment on backend (signature verification)
      await AppSettings.verifyRazorpayPayment(
        razorpayPaymentId: response.paymentId ?? "",
        razorpayOrderId: response.orderId ?? "",
        razorpaySignature: response.signature ?? "",
      );

      // 3) Save topup
      await AppSettings.addAdvanceTopUp(
        widget.supplierId,
        AppSettings.customerId,
        amt,
        "razorpay",
        gatewayTxnId: response.paymentId ?? "",
      );

      if (!mounted) return;
      Navigator.pop(context, true);
    } catch (e) {
      if (!mounted) return;
      setState(() {
        errorText = "Payment captured but verification failed. Contact support.";
        isPaying = false;
      });
    }
  }

  void _onRazorpayError(PaymentFailureResponse response) {
    if (!mounted) return;
    setState(() {
      isPaying = false;
      errorText = "Payment failed. Please try again.";
    });
  }

  void _onRazorpayExternalWallet(ExternalWalletResponse response) {
    // optional
  }

  @override
  Widget build(BuildContext context) {
    final amount = _readAmount();

    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.white,
        leading: IconButton(
          icon: const Icon(Icons.close, color: Colors.black),
          onPressed: () => Navigator.pop(context),
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          children: [
            const SizedBox(height: 24),

            AnimatedSwitcher(
              duration: const Duration(milliseconds: 250),
              child: Text(
                widget.supplierName,
                key: ValueKey(widget.supplierName),
                style: fontTextStyle(16, Colors.black, FontWeight.w600),
              ),
            ),
            const SizedBox(height: 6),
            Text("Credit Account · Top Up", style: fontTextStyle(12, Colors.grey, FontWeight.w400)),

            const SizedBox(height: 24),

            // ✅ Editable amount
            AnimatedContainer(
              duration: const Duration(milliseconds: 250),
              padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 8),
              decoration: BoxDecoration(
                color: const Color(0xFFEFF4FF),
                borderRadius: BorderRadius.circular(16),
                border: Border.all(
                  color: errorText != null ? Colors.red.withOpacity(0.5) : Colors.transparent,
                ),
              ),
              child: TextField(
                controller: amountCtrl,
                keyboardType: TextInputType.number,
                textAlign: TextAlign.center,
                onChanged: (_) {
                  if (errorText != null) setState(() => errorText = null);
                  setState(() {}); // animate amount changes
                },
                style: fontTextStyle(26, const Color(0xFF1D7AFC), FontWeight.w700),
                decoration: const InputDecoration(
                  border: InputBorder.none,
                  prefixText: "₹",
                ),
              ),
            ),

            const SizedBox(height: 8),
            Text("What is it for?", style: fontTextStyle(12, Colors.grey, FontWeight.w400)),

            if (errorText != null) ...[
              const SizedBox(height: 12),
              AnimatedOpacity(
                opacity: 1,
                duration: const Duration(milliseconds: 250),
                child: Text(errorText!, style: fontTextStyle(12, Colors.red, FontWeight.w500)),
              ),
            ],

            const SizedBox(height: 18),

            // ✅ UPI App Selector
            if (_apps.isNotEmpty) ...[
              Align(
                alignment: Alignment.centerLeft,
                child: Text("Pay using UPI App", style: fontTextStyle(12, const Color(0xFF3B3B3B), FontWeight.w600)),
              ),
              const SizedBox(height: 10),
              SizedBox(
                height: 56,
                child: ListView.separated(
                  scrollDirection: Axis.horizontal,
                  itemCount: _apps.length,
                  separatorBuilder: (_, __) => const SizedBox(width: 10),
                  itemBuilder: (_, i) {
                    final app = _apps[i];
                    final selected = _selectedUpiApp?.name == app.name;

                    return GestureDetector(
                      onTap: () => setState(() => _selectedUpiApp = app),
                      child: AnimatedContainer(
                        duration: const Duration(milliseconds: 200),
                        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
                        decoration: BoxDecoration(
                          color: selected ? const Color(0xFF1D7AFC).withOpacity(0.12) : Colors.white,
                          borderRadius: BorderRadius.circular(14),
                          border: Border.all(
                            color: selected ? const Color(0xFF1D7AFC) : const Color(0xFFE0E0E0),
                          ),
                        ),
                        child: Row(
                          children: [
                            if (app.icon != null) Image.memory(app.icon!, width: 22, height: 22),
                            const SizedBox(width: 8),
                            Text(app.name, style: fontTextStyle(12, const Color(0xFF3B3B3B), FontWeight.w500)),
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
            ],

            const Spacer(),

            // ✅ Buttons (Animated)
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 250),
              child: isPaying
                  ? SizedBox(
                key: const ValueKey("loading"),
                width: double.infinity,
                height: 48,
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFF1D7AFC),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
                  ),
                  onPressed: null,
                  child: const SizedBox(
                    width: 22,
                    height: 22,
                    child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
                  ),
                ),
              )
                  : Column(
                key: const ValueKey("buttons"),
                children: [
                  // ✅ Confirm = UPI app selected
                  SizedBox(
                    width: double.infinity,
                    height: 48,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF1D7AFC),
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
                      ),
                      onPressed: (_apps.isNotEmpty) ? _payViaSelectedUpiApp : null,
                      child: Text(
                        _apps.isNotEmpty
                            ? "Confirm (UPI: ${_selectedUpiApp?.name ?? ''})"
                            : "Confirm (UPI not available)",
                        style: fontTextStyle(14, Colors.white, FontWeight.w600),
                      ),
                    ),
                  ),
                  const SizedBox(height: 10),

                  // ✅ Razorpay = best for PhonePe/cards/netbanking
                  SizedBox(
                    width: double.infinity,
                    height: 48,
                    child: OutlinedButton(
                      style: OutlinedButton.styleFrom(
                        side: const BorderSide(color: Color(0xFF1D7AFC)),
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
                      ),
                      onPressed: _payViaRazorpay,
                      child: Text(
                        "Pay via Razorpay / PhonePe",
                        style: fontTextStyle(14, const Color(0xFF1D7AFC), FontWeight.w600),
                      ),
                    ),
                  ),

                  const SizedBox(height: 10),
                  Text(
                    "Amount: ₹${amount.toStringAsFixed(0)}",
                    style: fontTextStyle(10, const Color(0xFF757575), FontWeight.w400),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
