import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:qpay/screens/groups/models/group_batch_model.dart';
import 'package:qpay/screens/groups/models/batch_item_update_model.dart';
import 'package:qpay/screens/groups/models/recipient_group_model.dart';
import 'package:qpay/models/responsive_policy.dart';
import 'package:qpay/screens/groups/controllers/batch_controller.dart';
import 'package:qpay/screens/provider/provider_controller.dart';
import 'package:qpay/widgets/app_snack_bar.dart';
import 'package:shared_preferences/shared_preferences.dart';

class BatchCreateScreen extends StatefulWidget {
  final RecipientGroup group;

  const BatchCreateScreen({super.key, required this.group});

  @override
  State<BatchCreateScreen> createState() => _BatchCreateScreenState();
}

class _BatchCreateScreenState extends State<BatchCreateScreen> {
  late BatchController batchController;
  late ProviderController providerController;
  final _formKey = GlobalKey<FormState>();
  final _descriptionController = TextEditingController();
  final _amountController = TextEditingController();
  final _debitPhoneController = TextEditingController();
  String _currency = 'USD';
  bool _loadingDropdowns = true;

  @override
  void initState() {
    super.initState();
    batchController = BatchController(context);
    providerController = ProviderController(context);
    // Sync listeners so the UI rebuilds when either controller changes
    batchController.addListener(_onControllerChange);
    providerController.addListener(_onControllerChange);
    _init();
  }

  void _onControllerChange() {
    if (!mounted) return;
    setState(() {
      // When products are available and a selected product exists with a non-zero
      // defaultAmount, populate the amount field (only if it's empty or was cleared).
      if (providerController.model.products.isNotEmpty &&
          providerController.model.selectedProduct != null &&
          _amountController.text.isEmpty) {
        final product = providerController.model.selectedProduct!;
        if (product.defaultAmount > 0) {
          _amountController.text = product.defaultAmount.toStringAsFixed(2);
        }
      }
    });
  }

  Future<void> _init() async {
    final prefs = await SharedPreferences.getInstance();
    if (prefs.containsKey('phone')) {
      _debitPhoneController.text = prefs.getString('phone')!;
    }
    await Future.wait([
      providerController.loadProviders(_currency),
      batchController.loadProcessors(_currency),
    ]);
    if (mounted) setState(() => _loadingDropdowns = false);
  }

  @override
  void dispose() {
    batchController.removeListener(_onControllerChange);
    providerController.removeListener(_onControllerChange);
    batchController.dispose();
    providerController.dispose();
    _descriptionController.dispose();
    _amountController.dispose();
    _debitPhoneController.dispose();
    super.dispose();
  }

  Future<void> _submit() async {
    if (!_formKey.currentState!.validate()) return;

    final amount = double.tryParse(_amountController.text.trim());
    if (amount == null || amount <= 0) {
      AppSnackBar.show(context, 'Please enter a valid amount.');
      return;
    }

    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';
    final workspaceId = prefs.getString('workspaceId') ?? '';

    final req = CreateBatchRequest(
      recipientGroupId: widget.group.id ?? '',
      userId: userId,
      workspaceId: workspaceId,
      currency: _currency,
      description: _descriptionController.text.trim(),
      amount: amount,
    );

    // Step 1: Create the batch
    final result = await batchController.createBatch(req);
    if (!mounted) return;

    if (result.isSuccess) {
      final batch = result.data!;

      // Step 2: Update batch items with selected provider & product
      final selectedProvider = providerController.model.selectedProvider;
      final selectedProduct = providerController.model.selectedProduct;

      if (selectedProvider != null && batch.id != null) {
        await _updateBatchItems(
          batch.id!,
          selectedProvider,
          selectedProduct,
          workspaceId,
        );
      }

      if (!mounted) return;
      context.pushReplacement('/groups/batches/${batch.id}');
    } else {
      AppSnackBar.showError(context, result.error ?? 'Failed to create batch.');
    }
  }

  Future<void> _updateBatchItems(
    String batchId,
    BillProvider provider,
    BillProduct? product,
    String workspaceId,
  ) async {
    // Fetch the batch items so we can update them
    final itemsResult = await batchController.listBatchItems(batchId);
    if (!mounted || !itemsResult.isSuccess) return;

    if (itemsResult.data!.isEmpty) return;

    final updateItems = itemsResult.data!.map((item) {
      return GroupBatchItemUpdateRequest(
        id: item.id,
        amount: item.amount,
        recipientName: item.recipientName,
        recipientPhone: item.recipientPhone,
        providerImage: provider.image,
        providerLabel: provider.label,
        billClientId: provider.clientId,
        billName: provider.name,
        billProductName: product?.name ?? '',
      );
    }).toList();

    final updateList = GroupBatchItemUpdateList(
      items: updateItems,
      workspaceId: workspaceId,
    );

    await batchController.updateBatchItems(batchId, updateList);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('New Batch'), centerTitle: true),
      body: ListenableBuilder(
        listenable: Listenable.merge([batchController, providerController]),
        builder: (context, _) {
          if (_loadingDropdowns) {
            return const Center(child: CircularProgressIndicator());
          }
          return Align(
            alignment: Alignment.topCenter,
            child: LayoutBuilder(
              builder: (context, constraints) {
                final width = constraints.maxWidth > ResponsivePolicy.md
                    ? ResponsivePolicy.md.toDouble()
                    : constraints.maxWidth;
                return SizedBox(
                  width: width,
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.all(20),
                    child: Form(
                      key: _formKey,
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          // Row 1: Description + Currency
                          Row(
                            children: [
                              Expanded(
                                flex: 2,
                                child: TextFormField(
                                  controller: _descriptionController,
                                  textInputAction: TextInputAction.next,
                                  decoration: InputDecoration(
                                    labelText: 'Description (optional)',
                                    hintText:
                                        'e.g. Monthly salaries for January',
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(12),
                                    ),
                                  ),
                                ),
                              ),
                              const SizedBox(width: 12),
                              Expanded(
                                child: DropdownButtonFormField<String>(
                                  initialValue: _currency,
                                  decoration: InputDecoration(
                                    labelText: 'Currency',
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(12),
                                    ),
                                  ),
                                  items: const [
                                    DropdownMenuItem(
                                      value: 'USD',
                                      child: Text('USD'),
                                    ),
                                    DropdownMenuItem(
                                      value: 'ZWG',
                                      child: Text('ZWG'),
                                    ),
                                  ],
                                  onChanged: (v) {
                                    if (v != null) _updateCurrency(v);
                                  },
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 16),
                          // Row 2: Provider + Product
                          Row(
                            children: [
                              Expanded(child: _buildProviderDropdown()),
                              const SizedBox(width: 12),
                              Expanded(child: _buildProductDropdown()),
                            ],
                          ),
                          const SizedBox(height: 16),
                          // Row 3: Amount + Phone
                          Row(
                            children: [
                              Expanded(
                                flex: 1,
                                child: TextFormField(
                                  controller: _amountController,
                                  readOnly: providerController
                                      .model
                                      .products
                                      .isNotEmpty,
                                  keyboardType:
                                      const TextInputType.numberWithOptions(
                                        decimal: true,
                                      ),
                                  textInputAction: TextInputAction.next,
                                  decoration: InputDecoration(
                                    labelText:
                                        'Amount each recipient will receive',
                                    hintText:
                                        providerController
                                            .model
                                            .products
                                            .isNotEmpty
                                        ? 'Set by product'
                                        : 'Amount',
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(12),
                                    ),
                                  ),
                                  validator: (v) =>
                                      (v == null || v.trim().isEmpty)
                                      ? 'Required'
                                      : null,
                                ),
                              ),
                              const SizedBox(width: 12),
                              Expanded(
                                flex: 1,
                                child: TextFormField(
                                  controller: _debitPhoneController,
                                  keyboardType: TextInputType.phone,
                                  textInputAction: TextInputAction.done,
                                  decoration: InputDecoration(
                                    labelText: 'Your Phone Number',
                                    hintText: '263773000000',
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(12),
                                    ),
                                  ),
                                  validator: (v) =>
                                      (v == null || v.trim().isEmpty)
                                      ? 'Phone number is required'
                                      : null,
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 32),
                          ElevatedButton(
                            onPressed: batchController.model.isActing
                                ? null
                                : _submit,
                            style: ElevatedButton.styleFrom(
                              padding: const EdgeInsets.symmetric(vertical: 16),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                            child: batchController.model.isActing
                                ? const SizedBox(
                                    height: 20,
                                    width: 20,
                                    child: CircularProgressIndicator(
                                      strokeWidth: 2,
                                      color: Colors.white,
                                    ),
                                  )
                                : const Text(
                                    'Create Batch',
                                    style: TextStyle(fontSize: 16),
                                  ),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }

  Widget _buildProviderDropdown() {
    final providers = providerController.model.providers;
    final isDark = Theme.of(context).brightness == Brightness.dark;

    if (providerController.model.isLoadingProviders) {
      return const SizedBox(
        height: 56,
        child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
      );
    }

    if (providers.isEmpty) {
      return const SizedBox(
        height: 56,
        child: Center(child: Text('No providers available')),
      );
    }

    return DropdownButtonFormField<BillProvider>(
      initialValue: providerController.model.selectedProvider,
      isExpanded: true,
      decoration: InputDecoration(
        labelText: 'Provider',
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
        contentPadding: const EdgeInsets.symmetric(
          horizontal: 12,
          vertical: 14,
        ),
      ),
      items: providers.map((provider) {
        return DropdownMenuItem<BillProvider>(
          value: provider,
          child: Row(
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Image.asset(
                  'assets/${provider.image}',
                  width: 24,
                  height: 24,
                  errorBuilder: (_, __, ___) =>
                      const Icon(Icons.payment_rounded, size: 20),
                ),
              ),
              const SizedBox(width: 8),
              Flexible(
                child: Text(
                  provider.name,
                  style: TextStyle(
                    fontSize: 13,
                    color: isDark ? Colors.white : Colors.black87,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ],
          ),
        );
      }).toList(),
      onChanged: (provider) {
        if (provider != null) {
          _amountController.clear();
          providerController.selectProvider(provider);
        }
      },
    );
  }

  Widget _buildProductDropdown() {
    final products = providerController.model.products;
    final isDark = Theme.of(context).brightness == Brightness.dark;

    if (providerController.model.selectedProvider == null) {
      return InputDecorator(
        decoration: InputDecoration(
          labelText: 'Product',
          border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
          contentPadding: const EdgeInsets.symmetric(
            horizontal: 12,
            vertical: 14,
          ),
        ),
        child: Text(
          'Select a provider first',
          style: TextStyle(fontSize: 13, color: Colors.grey.shade500),
        ),
      );
    }

    if (providerController.model.isLoadingProducts) {
      return const SizedBox(
        height: 56,
        child: Center(child: CircularProgressIndicator(strokeWidth: 2)),
      );
    }

    if (products.isEmpty) {
      return InputDecorator(
        decoration: InputDecoration(
          labelText: 'Product',
          border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
          contentPadding: const EdgeInsets.symmetric(
            horizontal: 12,
            vertical: 14,
          ),
        ),
        child: Text(
          'No products',
          style: TextStyle(fontSize: 13, color: Colors.grey.shade500),
        ),
      );
    }

    return DropdownButtonFormField<BillProduct>(
      value: providerController.model.selectedProduct,
      isExpanded: true,
      decoration: InputDecoration(
        labelText: 'Product',
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
        contentPadding: const EdgeInsets.symmetric(
          horizontal: 12,
          vertical: 14,
        ),
      ),
      items: products.map((product) {
        return DropdownMenuItem<BillProduct>(
          value: product,
          child: Text(
            '${product.displayName.isNotEmpty ? product.displayName : product.name} - \$${product.defaultAmount}',
            style: TextStyle(
              fontSize: 13,
              color: isDark ? Colors.white : Colors.black87,
            ),
            overflow: TextOverflow.ellipsis,
          ),
        );
      }).toList(),
      onChanged: (product) {
        if (product != null) {
          providerController.selectProduct(product);
          if (product.defaultAmount > 0) {
            _amountController.text = product.defaultAmount.toStringAsFixed(2);
          }
        }
      },
    );
  }

  void _updateCurrency(String v) {
    setState(() => _currency = v);
    providerController.loadProviders(v);
  }
}
