import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

import 'package:doormile/shared/models/models.dart';
import 'package:doormile/core/theme/app_colors.dart';
import 'package:doormile/core/utils/snackbar_utils.dart';
import 'package:doormile/core/theme/app_theme.dart';
import 'package:doormile/core/widgets/common.dart';

class LiveTrackingScreen extends StatefulWidget {
  final Order? order;
  const LiveTrackingScreen({super.key, this.order});

  @override
  State<LiveTrackingScreen> createState() => _LiveTrackingScreenState();
}

class _LiveTrackingScreenState extends State<LiveTrackingScreen> {
  static const _defaultCenter = LatLng(11.02, 76.95);

  WebSocketChannel? _channel;
  GoogleMapController? _mapController;

  LatLng _milerPosition = _defaultCenter;
  Set<Marker> _markers = {};
  int _etaSeconds = 0;
  String _milerName = 'Assigning Miler...';
  String _status = 'In transit';
  Timer? _etaTimer;

  @override
  void initState() {
    super.initState();
    _connectWebSocket();
  }

  void _connectWebSocket() {
    final bookingId = widget.order?.id;
    if (bookingId == null || bookingId.isEmpty) return;
    try {
      _channel = WebSocketChannel.connect(
        Uri.parse('ws://api.doormile.com/ws/bookings/$bookingId/track'),
      );
      _channel!.stream.listen(
        _onMessage,
        onError: (e) => debugPrint('WS error: $e'),
        onDone: () => debugPrint('WS closed'),
        cancelOnError: false,
      );
    } catch (e) {
      debugPrint('WS connect error: $e');
    }
  }

  void _onMessage(dynamic raw) {
    final Map<String, dynamic> data;
    try {
      data = jsonDecode(raw as String) as Map<String, dynamic>;
    } catch (e) {
      debugPrint('WS parse error: $e');
      return;
    }

    final lat = (data['lat'] as num?)?.toDouble();
    final lon = (data['lon'] as num?)?.toDouble();
    final etaMinutes = (data['eta_minutes'] as num?)?.toInt();
    final milerName = data['miler_name'] as String?;
    final status = data['status'] as String?;
    bool positionChanged = false;

    if (!mounted) return;

    setState(() {
      if (milerName != null && milerName.isNotEmpty) {
        _milerName = milerName;
      }
      if (status != null && status.isNotEmpty) {
        _status = status;
      }
      if (lat != null && lon != null && (lat != 0.0 || lon != 0.0)) {
        _milerPosition = LatLng(lat, lon);
        positionChanged = true;
        _markers = {
          Marker(
            markerId: const MarkerId('miler'),
            position: _milerPosition,
            infoWindow: InfoWindow(title: _milerName),
          ),
        };
      }
      if (etaMinutes != null) {
        _etaSeconds = etaMinutes * 60;
      }
    });

    if (etaMinutes != null) _restartEtaTimer();

    if (positionChanged) {
      _mapController?.animateCamera(
        CameraUpdate.newLatLng(_milerPosition),
      );
    }
  }

  void _restartEtaTimer() {
    _etaTimer?.cancel();
    if (_etaSeconds <= 0) return;
    _etaTimer = Timer.periodic(const Duration(seconds: 1), (_) {
      if (!mounted) return;
      setState(() {
        if (_etaSeconds > 0) _etaSeconds--;
      });
    });
  }

  String get _etaLabel {
    if (_etaSeconds > 0) {
      return '${(_etaSeconds / 60).ceil()} min';
    }
    return widget.order?.eta ?? '—';
  }

  @override
  void dispose() {
    _etaTimer?.cancel();
    _channel?.sink.close();
    _mapController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final id = widget.order?.id ?? 'DM-CHN-BLR-7741';

    return Scaffold(
      backgroundColor: AppColors.surface,
      body: Stack(
        children: [
          Positioned.fill(
            child: GoogleMap(
              initialCameraPosition: const CameraPosition(
                target: _defaultCenter,
                zoom: 14,
              ),
              markers: _markers,
              onMapCreated: (controller) => _mapController = controller,
              myLocationButtonEnabled: false,
              zoomControlsEnabled: false,
            ),
          ),
          SafeArea(
            child: Padding(
              padding: const EdgeInsets.all(12),
              child: Row(
                children: [
                  _circleBtn(Icons.arrow_back, () => Navigator.pop(context)),
                  const SizedBox(width: 10),
                  Expanded(
                    child: Text('Live Tracking',
                        style: AppTheme.headlineSm.copyWith(color: AppColors.primary),
                        overflow: TextOverflow.ellipsis),
                  ),
                  const SizedBox(width: 8),
                  StatusChip(
                    label: 'EV Priority',
                    icon: Icons.eco,
                    color: AppColors.tertiary,
                    bg: Colors.white,
                  ),
                ],
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Container(
              width: double.infinity,
              decoration: const BoxDecoration(
                color: AppColors.surface,
                borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
                boxShadow: [
                  BoxShadow(color: Color(0x1A000000), blurRadius: 24, offset: Offset(0, -6)),
                ],
              ),
              child: SafeArea(
                top: false,
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(16, 14, 16, 16),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Expanded(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text('PARCEL ID',
                                    style: AppTheme.caption.copyWith(letterSpacing: 1)),
                                Text(id,
                                    style: AppTheme.headlineSm
                                        .copyWith(fontWeight: FontWeight.w700)),
                              ],
                            ),
                          ),
                          StatusChip(
                            label: _status,
                            color: AppColors.tertiary,
                            bg: AppColors.tertiaryFixed.withValues(alpha: 0.5),
                          ),
                        ],
                      ),
                      const SizedBox(height: 4),
                      Text('ETA $_etaLabel',
                          style: AppTheme.labelMd.copyWith(color: AppColors.primary)),
                      const SizedBox(height: 16),
                      const _MileStepper(activeIndex: 2),
                      const SizedBox(height: 16),
                      _riderCard(context),
                      const SizedBox(height: 12),
                      const EcoBanner(
                          text: 'Eco-Friendly Journey · saving 1.2kg of CO₂ on this delivery.'),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _circleBtn(IconData icon, VoidCallback onTap) {
    return Material(
      color: Colors.white,
      shape: const CircleBorder(),
      elevation: 2,
      child: InkWell(
        onTap: onTap,
        customBorder: const CircleBorder(),
        child: SizedBox(
            width: 40, height: 40, child: Icon(icon, color: AppColors.primary, size: 22)),
      ),
    );
  }

  Widget _riderCard(BuildContext context) {
    return AppCard(
      color: AppColors.surfaceContainerLow,
      child: Column(
        children: [
          Row(
            children: [
              const CircleAvatar(
                radius: 24,
                backgroundColor: AppColors.primaryFixed,
                child: Icon(Icons.person, color: AppColors.primary, size: 28),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(_milerName,
                        style: AppTheme.labelMd.copyWith(fontWeight: FontWeight.w700)),
                    Row(
                      children: [
                        StatusChip(
                            label: 'EV',
                            icon: Icons.bolt,
                            color: AppColors.tertiary,
                            bg: AppColors.tertiaryFixed.withValues(alpha: 0.5)),
                        const SizedBox(width: 6),
                        Flexible(
                          child: Text('KA-01-EV-4412',
                              style: AppTheme.caption, overflow: TextOverflow.ellipsis),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text('★ 4.9',
                      style: AppTheme.labelMd.copyWith(color: AppColors.warning)),
                  Text('4821 trips', style: AppTheme.caption),
                ],
              ),
            ],
          ),
          const SizedBox(height: 14),
          Row(
            children: [
              Expanded(
                child: OutlinedButton.icon(
                  onPressed: () async {
                    final uri = Uri(scheme: 'tel', path: '+919876543210');
                    try {
                      await launchUrl(uri);
                    } catch (e) {
                      if (context.mounted) _toast(context, 'Could not launch dialer.');
                    }
                  },
                  icon: const Icon(Icons.call, size: 18),
                  label: const Text('Call Rider'),
                  style: OutlinedButton.styleFrom(
                    foregroundColor: AppColors.primary,
                    side: const BorderSide(color: AppColors.primary),
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(12)),
                  ),
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: ElevatedButton.icon(
                  onPressed: () => Navigator.pushNamed(
                    context,
                    '/chat',
                    arguments: {
                      'milerName': _milerName,
                      'bookingId': widget.order?.id ?? '',
                    },
                  ),
                  icon: const Icon(Icons.chat_bubble_outline, size: 18),
                  label: const Text('Chat'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: AppColors.primary,
                    foregroundColor: Colors.white,
                    elevation: 0,
                    padding: const EdgeInsets.symmetric(vertical: 12),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(12)),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  void _toast(BuildContext context, String msg) {
    SnackbarUtils.showError(context, msg);
  }
}

class _MileStepper extends StatelessWidget {
  final int activeIndex;
  const _MileStepper({required this.activeIndex});

  static const _stops = [
    ('Booked', AppColors.primary),
    ('First Mile', AppColors.firstMile),
    ('Mid Mile', AppColors.midMile),
    ('Last Mile', AppColors.lastMile),
  ];

  @override
  Widget build(BuildContext context) {
    return Row(
      children: List.generate(_stops.length, (i) {
        final done = i <= activeIndex;
        final stop = _stops[i];
        return Expanded(
          child: Column(
            children: [
              Row(
                children: [
                  Expanded(
                    child: Container(
                      height: 3,
                      color: i == 0
                          ? Colors.transparent
                          : (i <= activeIndex ? stop.$2 : AppColors.surfaceContainerHigh),
                    ),
                  ),
                  Container(
                    width: 14,
                    height: 14,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: done ? stop.$2 : AppColors.surfaceContainerHigh,
                      border: Border.all(
                          color: done ? stop.$2 : AppColors.outlineVariant, width: 2),
                    ),
                    child: done
                        ? const Icon(Icons.check, size: 8, color: Colors.white)
                        : null,
                  ),
                  Expanded(
                    child: Container(
                      height: 3,
                      color: i == _stops.length - 1
                          ? Colors.transparent
                          : (i < activeIndex
                              ? _stops[i + 1].$2
                              : AppColors.surfaceContainerHigh),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 6),
              Text(stop.$1,
                  style: AppTheme.caption.copyWith(
                    color: done ? stop.$2 : AppColors.onSurfaceVariant,
                    fontWeight: i == activeIndex ? FontWeight.w700 : FontWeight.w500,
                  )),
            ],
          ),
        );
      }),
    );
  }
}
