import 'dart:io' show Platform;
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import '../api_client.dart';
import '../map_utils.dart';

// ── Brand tokens ──────────────────────────────────────────────────────────────
class _Brand {
  static const bg = Color(0xFF0F1114);
  static const card = Color(0xFF21252D);
  static const amber = Color(0xFFFF9500);
  static const amberGlow = Color(0x33FF9500);
  static const textPrimary = Color(0xFFF2F2F2);
  static const textMuted = Color(0xFF8A8F99);
  static const divider = Color(0xFF2C3040);
  static const green = Color(0xFF34C759);
  static const error = Color(0xFFFF4545);
}

// ─────────────────────────────────────────────────────────────────────────────

class OrderDetailScreen extends StatefulWidget {
  const OrderDetailScreen({
    super.key,
    required this.orderId,
    required this.onUnauthorized,
    required this.onComplete,
  });

  final int orderId;
  final VoidCallback onUnauthorized;
  final VoidCallback onComplete;

  @override
  State<OrderDetailScreen> createState() => _OrderDetailScreenState();
}

class _OrderDetailScreenState extends State<OrderDetailScreen>
    with SingleTickerProviderStateMixin {
  late Dio _dio;
  Map? _order;
  bool _loading = true;
  String? _error;
  bool _completing = false;
  final _otpController = TextEditingController();
  String? _otpError;

  late final AnimationController _fadeCtrl;
  late final Animation<double> _fadeAnim;

  @override
  void initState() {
    super.initState();
    _dio = createApiClient(widget.onUnauthorized);
    _fadeCtrl = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 450));
    _fadeAnim = CurvedAnimation(parent: _fadeCtrl, curve: Curves.easeOut);
    _load();
  }

  @override
  void dispose() {
    _fadeCtrl.dispose();
    _otpController.dispose();
    super.dispose();
  }

  Future<void> _load() async {
    setState(() {
      _loading = true;
      _error = null;
    });
    try {
      final r = await _dio.get('/api/orders/${widget.orderId}');
      if (!mounted) return;
      setState(() {
        _order = (r.data is Map && r.data['data'] != null)
            ? r.data['data'] as Map
            : null;
        _loading = false;
      });
      _fadeCtrl.forward(from: 0);
    } catch (e) {
      if (e is DioException && e.response?.statusCode == 401) {
        widget.onUnauthorized();
        return;
      }
      if (mounted) {
        setState(() {
          _loading = false;
          _error = 'Failed to load order';
        });
        _fadeCtrl.forward(from: 0);
      }
    }
  }

  Future<void> _completeDelivery() async {
    final code = _otpController.text.trim();
    if (code.length != 4) {
      setState(() => _otpError = 'Enter 4-digit OTP');
      return;
    }
    setState(() {
      _otpError = null;
      _completing = true;
    });
    try {
      await _dio.post('/api/orders/complete/${widget.orderId}',
          data: {'otp_code': code});
      if (!mounted) return;
      widget.onComplete();
      Navigator.of(context).pop(true);
    } catch (e) {
      if (e is DioException && e.response?.statusCode == 401) {
        widget.onUnauthorized();
        return;
      }
      if (mounted) {
        final msg = e is DioException && e.response?.data is Map
            ? (e.response!.data as Map)['message']?.toString()
            : 'Invalid OTP or failed';
        setState(() {
          _otpError = msg ?? 'Failed';
          _completing = false;
        });
      }
    }
  }

  void _openMaps() async {
    final loc = _order?['location'];
    if (loc == null) return;
    final lat = (loc['latitude'] as num?)?.toDouble();
    final lng = (loc['longitude'] as num?)?.toDouble();
    final address = loc['address_name']?.toString();
    final plusCode = loc['plus_code']?.toString();
    // Prefer stored Plus Code (set by user app) so directions match what user saved
    final destination = (plusCode?.trim().isNotEmpty == true)
        ? plusCode!.trim()
        : (lat != null && lng != null)
            ? buildMapDestination(lat, lng)
            : null;
    Uri? uri;
    if (destination != null && destination.isNotEmpty) {
      final encoded = Uri.encodeComponent(destination);
      if (Platform.isAndroid) {
        uri = Uri.parse('google.navigation:q=$encoded');
      } else {
        uri = Uri.parse('https://www.google.com/maps/dir/?api=1&destination=$encoded&travelmode=driving');
      }
    } else if (address != null && address.isNotEmpty) {
      uri = Uri.parse(
          'https://www.google.com/maps/search/?api=1&query=${Uri.encodeComponent(address)}');
    }
    if (uri == null) return;
    try {
      await launchUrl(uri, mode: LaunchMode.externalApplication);
    } catch (_) {}
  }

  void _callCustomer() async {
    final phone = _order?['user_phone']?.toString();
    if (phone == null || phone.isEmpty) return;
    final uri = Uri(scheme: 'tel', path: phone);
    if (await canLaunchUrl(uri)) await launchUrl(uri);
  }

  String _formatAmount(dynamic v) {
    if (v == null) return '—';
    final d = double.tryParse(v.toString()) ?? 0;
    final s = d.toStringAsFixed(0).split('');
    final buf = StringBuffer();
    for (int i = 0; i < s.length; i++) {
      if (i > 0 && (s.length - i) % 3 == 0) buf.write(',');
      buf.write(s[i]);
    }
    return buf.toString();
  }

  /// Driver sees plus code (delivery location); friendly name is for the ordering user only.
  String _locationDisplayText(Map location) {
    final plusCode = location['plus_code']?.toString().trim();
    if (plusCode != null && plusCode.isNotEmpty) return plusCode;
    final lat = location['latitude'];
    final lng = location['longitude'];
    if (lat != null && lng != null) return '${lat}, $lng';
    final name = location['address_name']?.toString().trim();
    if (name != null && name.isNotEmpty) return name;
    return '—';
  }

  Map? _orderSummary(Map o) {
    final summary = o['order_summary'];
    if (summary == null || summary is! Map) return null;
    return summary;
  }

  String _fuelPricePerLiterText(Map o) {
    final m = _orderSummary(o);
    if (m == null) return '—';
    final v = m['price_per_liter'];
    if (v == null) return '—';
    return '${_formatAmount(v)} UGX';
  }

  String? _orderSummaryText(Map o) {
    final summary = o['order_summary'];
    if (summary == null || summary is! Map) return null;
    final m = summary;
    final orderType = o['order_type']?.toString() ?? '';
    if (orderType == 'gas') {
      final type = m['type']?.toString() ?? '—';
      final brand = m['brand']?.toString() ?? '—';
      final size = m['size']?.toString() ?? '—';
      return '$type · $brand · $size';
    }
    if (orderType == 'fuel') {
      final brand = m['brand']?.toString() ?? '—';
      final fuelType = m['fuel_type']?.toString() ?? '—';
      final liters = m['liters'];
      final L = liters != null
          ? (liters is num ? liters.toInt() : liters.toString())
          : '—';
      final pricePerL = m['price_per_liter'];
      final priceStr = pricePerL != null
          ? '${_formatAmount(pricePerL)} UGX/L'
          : null;
      if (priceStr != null) {
        return '$brand · $fuelType · ${L}L @ $priceStr';
      }
      return '$brand · $fuelType · ${L}L';
    }
    if (orderType == 'rescue') return m['service']?.toString() ?? '—';
    if (orderType == 'shop') {
      final n = m['items_count'];
      final count = n != null ? (n is num ? n.toInt() : n.toString()) : '0';
      return '$count item(s)';
    }
    return null;
  }

  IconData _typeIcon(String orderType) {
    switch (orderType) {
      case 'gas':
        return Icons.propane_tank_rounded;
      case 'fuel':
        return Icons.local_gas_station_rounded;
      case 'rescue':
        return Icons.emergency_rounded;
      case 'shop':
        return Icons.shopping_bag_rounded;
      default:
        return Icons.receipt_long_rounded;
    }
  }

  String _formatDate(String raw) {
    try {
      final dt = DateTime.parse(raw).toLocal();
      final months = [
        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
      ];
      final h = dt.hour.toString().padLeft(2, '0');
      final m = dt.minute.toString().padLeft(2, '0');
      return '${dt.day} ${months[dt.month - 1]} ${dt.year}  $h:$m';
    } catch (_) {
      return raw;
    }
  }

  @override
  Widget build(BuildContext context) {
    final appBar = AppBar(
      backgroundColor: _Brand.bg,
      elevation: 0,
      scrolledUnderElevation: 0,
      leading: IconButton(
        icon: const Icon(Icons.arrow_back_ios_new, size: 20, color: _Brand.textMuted),
        onPressed: () => Navigator.pop(context),
      ),
      title: Text(
        _order != null ? 'ORDER #${_order!['id']}' : 'ORDER DETAIL',
        style: const TextStyle(
          color: _Brand.textPrimary,
          fontSize: 16,
          fontWeight: FontWeight.w700,
        ),
      ),
    );

    if (_loading && _order == null) {
      return Scaffold(
        backgroundColor: _Brand.bg,
        appBar: appBar,
        body: const Center(
          child: SizedBox(
            width: 32,
            height: 32,
            child: CircularProgressIndicator(
              strokeWidth: 2.5,
              valueColor: AlwaysStoppedAnimation(_Brand.amber),
            ),
          ),
        ),
      );
    }

    if (_error != null || _order == null) {
      return Scaffold(
        backgroundColor: _Brand.bg,
        appBar: appBar,
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.receipt_long_rounded, color: _Brand.error, size: 48),
              const SizedBox(height: 16),
              Text(
                _error ?? 'Order not found',
                style: const TextStyle(color: _Brand.textPrimary, fontSize: 15),
              ),
            ],
          ),
        ),
      );
    }

    final o = _order!;
    final status = o['status']?.toString() ?? '';
    final orderType = o['order_type']?.toString() ?? '—';
    final location = o['location'];
    // Admin/driver see plus code (delivery location); friendly name is for user only.
    final addressText = location != null
        ? (_locationDisplayText(location))
        : '—';
    final summaryText = _orderSummaryText(o);
    final createdAt = o['created_at']?.toString();
    final canComplete = status == 'paid' || status == 'dispatched';

    return Scaffold(
      backgroundColor: _Brand.bg,
      appBar: appBar,
      body: FadeTransition(
        opacity: _fadeAnim,
        child: Column(
          children: [
            Expanded(
              child: SingleChildScrollView(
                padding: const EdgeInsets.fromLTRB(20, 8, 20, 20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    // Status chip
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                      decoration: BoxDecoration(
                        color: _Brand.amberGlow,
                        borderRadius: BorderRadius.circular(8),
                        border: Border.all(color: _Brand.amber.withOpacity(0.4)),
                      ),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(_typeIcon(orderType), color: _Brand.amber, size: 18),
                          const SizedBox(width: 8),
                          Text(
                            status.toUpperCase(),
                            style: const TextStyle(
                              color: _Brand.amber,
                              fontSize: 12,
                              fontWeight: FontWeight.w700,
                              letterSpacing: 1,
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 20),
                    _SectionLabel('ORDER DETAILS'),
                    const SizedBox(height: 12),
                    _InfoCard(children: [
                      _InfoRow(
                        icon: _typeIcon(orderType),
                        label: 'Service type',
                        value: orderType.toUpperCase(),
                        valueColor: _Brand.amber,
                      ),
                      if (summaryText != null) ...[
                        const _RowDivider(),
                        _InfoRow(
                          icon: Icons.inventory_2_rounded,
                          label: 'What was ordered',
                          value: summaryText,
                        ),
                      ],
                      if (orderType == 'fuel' && _orderSummary(o) != null) ...[
                        const _RowDivider(),
                        _InfoRow(
                          icon: Icons.local_gas_station_rounded,
                          label: 'Fuel type',
                          value: _orderSummary(o)!['fuel_type']?.toString() ?? '—',
                        ),
                        const _RowDivider(),
                        _InfoRow(
                          icon: Icons.sell_rounded,
                          label: 'Price per liter',
                          value: _fuelPricePerLiterText(o),
                          valueColor: _Brand.amber,
                        ),
                      ],
                      const _RowDivider(),
                      _InfoRow(
                        icon: Icons.location_on_rounded,
                        label: 'Delivery address',
                        value: addressText,
                      ),
                      if (createdAt != null) ...[
                        const _RowDivider(),
                        _InfoRow(
                          icon: Icons.calendar_today_rounded,
                          label: 'Date',
                          value: _formatDate(createdAt),
                        ),
                      ],
                    ]),
                    const SizedBox(height: 20),
                    _SectionLabel('CUSTOMER'),
                    const SizedBox(height: 12),
                    _CustomerCard(
                      phone: o['user_phone']?.toString(),
                      onCall: _callCustomer,
                      onMap: _openMaps,
                    ),
                    if (canComplete) ...[
                      const SizedBox(height: 24),
                      _SectionLabel('CONFIRM DELIVERY'),
                      const SizedBox(height: 12),
                      const Text(
                        'Enter the 4-digit OTP from the customer to confirm you are delivering the right order.',
                        style: TextStyle(
                          color: _Brand.textMuted,
                          fontSize: 12,
                          height: 1.4,
                        ),
                      ),
                      const SizedBox(height: 12),
                      TextField(
                        controller: _otpController,
                        keyboardType: TextInputType.number,
                        maxLength: 4,
                        style: const TextStyle(
                          fontFamily: 'RobotoMono',
                          fontSize: 24,
                          fontWeight: FontWeight.w700,
                          letterSpacing: 8,
                        ),
                        decoration: InputDecoration(
                          hintText: '••••',
                          errorText: _otpError,
                          counterText: '',
                          filled: true,
                          fillColor: _Brand.card,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(12),
                            borderSide: const BorderSide(color: _Brand.divider),
                          ),
                          enabledBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(12),
                            borderSide: BorderSide(
                                color: _otpError != null ? _Brand.error : _Brand.divider),
                          ),
                        ),
                        onChanged: (_) => setState(() => _otpError = null),
                      ),
                      const SizedBox(height: 16),
                      FilledButton(
                        onPressed: _completing ? null : _completeDelivery,
                        style: FilledButton.styleFrom(
                          backgroundColor: _Brand.green,
                          foregroundColor: _Brand.bg,
                          padding: const EdgeInsets.symmetric(vertical: 16),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(12),
                          ),
                        ),
                        child: _completing
                            ? const SizedBox(
                                height: 22,
                                width: 22,
                                child: CircularProgressIndicator(strokeWidth: 2),
                              )
                            : const Text('Complete Delivery'),
                      ),
                    ],
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// ── Info card ─────────────────────────────────────────────────────────────────

class _InfoCard extends StatelessWidget {
  final List<Widget> children;
  const _InfoCard({required this.children});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: _Brand.card,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: _Brand.divider),
      ),
      child: Column(children: children),
    );
  }
}

class _InfoRow extends StatelessWidget {
  final IconData icon;
  final String label;
  final String value;
  final Color? valueColor;

  const _InfoRow({
    required this.icon,
    required this.label,
    required this.value,
    this.valueColor,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            width: 32,
            height: 32,
            decoration: BoxDecoration(
              color: _Brand.amberGlow,
              borderRadius: BorderRadius.circular(8),
            ),
            child: Icon(icon, color: _Brand.amber, size: 15),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                    label,
                    style: const TextStyle(
                      color: _Brand.textMuted,
                      fontSize: 10,
                      letterSpacing: 1.5,
                      fontWeight: FontWeight.w600,
                    )),
                const SizedBox(height: 3),
                Text(
                  value,
                  style: TextStyle(
                    color: valueColor ?? _Brand.textPrimary,
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    height: 1.4,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _RowDivider extends StatelessWidget {
  const _RowDivider();

  @override
  Widget build(BuildContext context) =>
      const Padding(
        padding: EdgeInsets.symmetric(horizontal: 16),
        child: Divider(color: _Brand.divider, height: 1),
      );
}

class _SectionLabel extends StatelessWidget {
  final String text;
  const _SectionLabel(this.text);

  @override
  Widget build(BuildContext context) => Text(
        text,
        style: const TextStyle(
          color: _Brand.textMuted,
          fontSize: 10,
          letterSpacing: 2.5,
          fontWeight: FontWeight.w600,
        ),
      );
}

class _CustomerCard extends StatelessWidget {
  final String? phone;
  final VoidCallback onCall;
  final VoidCallback onMap;

  const _CustomerCard({
    this.phone,
    required this.onCall,
    required this.onMap,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: _Brand.card,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: _Brand.divider),
      ),
      child: Row(
        children: [
          Container(
            width: 44,
            height: 44,
            decoration: BoxDecoration(
              color: _Brand.amberGlow,
              shape: BoxShape.circle,
              border: Border.all(
                  color: _Brand.amber.withOpacity(0.3), width: 1.5),
            ),
            child: const Icon(Icons.person_rounded,
                color: _Brand.amber, size: 22),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('CUSTOMER',
                    style: TextStyle(
                      color: _Brand.textMuted,
                      fontSize: 10,
                      letterSpacing: 1.5,
                      fontWeight: FontWeight.w600,
                    )),
                const SizedBox(height: 2),
                Text(
                  phone ?? '—',
                  style: const TextStyle(
                    color: _Brand.textPrimary,
                    fontSize: 15,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ],
            ),
          ),
          if (phone != null && phone!.isNotEmpty)
            Padding(
              padding: const EdgeInsets.only(left: 8),
              child: IconButton(
                icon: const Icon(Icons.phone_rounded, color: _Brand.amber),
                onPressed: onCall,
                tooltip: 'Call customer',
              ),
            ),
          IconButton(
            icon: const Icon(Icons.map_rounded, color: _Brand.amber),
            onPressed: onMap,
            tooltip: 'Open in Maps',
          ),
        ],
      ),
    );
  }
}
