import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../l10n/app_localizations.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import '../models/delivery.dart';
import '../providers/providers.dart';
import '../api/client.dart';
import '../api/openapi_config.dart';
import '../models/delivery_commands.dart';
import '../components/map_sidebar_layout.dart';
import '../components/dark_mode_map.dart';
import '../components/unified_delivery_list.dart';
import '../components/loading_dialog.dart';
import '../components/photo_capture_dialog.dart';
import '../utils/toast_helper.dart';

class DeliveriesPage extends ConsumerStatefulWidget {
  final int routeFragmentId;
  final String routeName;
  final VoidCallback? onBack;
  final bool showAsEmbedded;
  final Delivery? selectedDelivery;
  final ValueChanged<Delivery?>? onDeliverySelected;

  const DeliveriesPage({
    super.key,
    required this.routeFragmentId,
    required this.routeName,
    this.onBack,
    this.showAsEmbedded = false,
    this.selectedDelivery,
    this.onDeliverySelected,
  });

  @override
  ConsumerState<DeliveriesPage> createState() => _DeliveriesPageState();
}

class _DeliveriesPageState extends ConsumerState<DeliveriesPage> {
  late ScrollController _listScrollController;
  Delivery? _selectedDelivery;
  int? _lastRouteFragmentId;

  @override
  void initState() {
    super.initState();
    _listScrollController = ScrollController();
    _selectedDelivery = widget.selectedDelivery;
  }

  @override
  void didUpdateWidget(DeliveriesPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.selectedDelivery != oldWidget.selectedDelivery) {
      setState(() {
        _selectedDelivery = widget.selectedDelivery;
      });
    }
  }

  @override
  void dispose() {
    _listScrollController.dispose();
    super.dispose();
  }

  Future<void> _autoScrollToFirstPending(List<Delivery> deliveries) async {
    final firstPendingIndex = deliveries.indexWhere((d) => !d.delivered && !d.isSkipped);

    if (_listScrollController.hasClients && firstPendingIndex != -1) {
      await Future.delayed(const Duration(milliseconds: 200));
      // Scroll to position first pending delivery at top of list
      // Each item is approximately 70 pixels tall
      final scrollOffset = firstPendingIndex * 70.0;
      _listScrollController.animateTo(
        scrollOffset.clamp(0, _listScrollController.position.maxScrollExtent),
        duration: const Duration(milliseconds: 500),
        curve: Curves.easeInOut,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final deliveriesData = ref.watch(deliveriesProvider(widget.routeFragmentId));
    final tokenAsync = ref.watch(authTokenProvider);
    final token = tokenAsync.hasValue ? tokenAsync.value : null;
    final l10n = AppLocalizations.of(context);

    // When embedded in sidebar, show only the delivery list with back button
    // This is a responsive sidebar that collapses like routes
    if (widget.showAsEmbedded) {
      final isExpanded = ref.watch(collapseStateProvider);

      return deliveriesData.when(
        data: (deliveries) {
          // Auto-scroll to first pending delivery when page loads or route changes
          if (_lastRouteFragmentId != widget.routeFragmentId) {
            _lastRouteFragmentId = widget.routeFragmentId;
            WidgetsBinding.instance.addPostFrameCallback((_) {
              _autoScrollToFirstPending(deliveries);
            });
          }

          // Responsive sidebar that changes width when collapsed (300px expanded, 80px collapsed)
          return AnimatedContainer(
            duration: const Duration(milliseconds: 300),
            width: isExpanded ? 300 : 80,
            child: Column(
              children: [
                // Header with back button
                Container(
                  padding: EdgeInsets.symmetric(
                    horizontal: isExpanded ? 12 : 0,
                    vertical: 8,
                  ),
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.surface,
                    border: Border(
                      bottom: BorderSide(
                        color: Theme.of(context).dividerColor,
                        width: 1,
                      ),
                    ),
                  ),
                  child: Row(
                    mainAxisAlignment: isExpanded
                        ? MainAxisAlignment.start
                        : MainAxisAlignment.center,
                    children: [
                      if (isExpanded) ...[
                        IconButton(
                          icon: const Icon(Icons.arrow_back),
                          onPressed: widget.onBack,
                          tooltip: 'Back to routes',
                        ),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            widget.routeName,
                            style: Theme.of(context).textTheme.titleLarge?.copyWith(
                              fontWeight: FontWeight.w700,
                            ),
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      ],
                      IconButton(
                        icon: Icon(isExpanded ? Icons.menu_open : Icons.menu),
                        onPressed: () {
                          ref.read(collapseStateProvider.notifier).toggle();
                        },
                        tooltip: isExpanded ? 'Collapse' : 'Expand',
                      ),
                    ],
                  ),
                ),
                // Delivery list
                Expanded(
                  child: UnifiedDeliveryListView(
                    deliveries: deliveries,
                    selectedDelivery: _selectedDelivery,
                    scrollController: _listScrollController,
                    onDeliverySelected: (delivery) {
                      setState(() {
                        _selectedDelivery = delivery;
                      });
                      // Notify parent about delivery selection
                      widget.onDeliverySelected?.call(delivery);
                    },
                    onItemAction: (delivery, action) {
                      _handleDeliveryAction(context, delivery, action, token);
                      _autoScrollToFirstPending(deliveries);
                    },
                    isCollapsed: !isExpanded,
                  ),
                ),
              ],
            ),
          );
        },
        loading: () => const Center(
          child: CircularProgressIndicator(),
        ),
        error: (error, stackTrace) => Center(
          child: Text(l10n.error(error.toString())),
        ),
      );
    }

    // When not embedded, show full page with map
    final routesData = ref.watch(deliveryRoutesProvider);

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.routeName),
        elevation: 0,
      ),
      body: SafeArea(
        child: deliveriesData.when(
        data: (deliveries) {
          // Auto-scroll to first pending delivery when page loads or route changes
          if (_lastRouteFragmentId != widget.routeFragmentId) {
            _lastRouteFragmentId = widget.routeFragmentId;
            WidgetsBinding.instance.addPostFrameCallback((_) {
              _autoScrollToFirstPending(deliveries);
            });
          }

          return routesData.when(
            data: (routes) {
              return MapSidebarLayout(
                      mapWidget: DarkModeMapComponent(
                        deliveries: deliveries,
                        selectedDelivery: _selectedDelivery,
                        onDeliverySelected: (delivery) {
                          setState(() {
                            _selectedDelivery = delivery;
                          });
                        },
                        onAction: (action) => _selectedDelivery != null
                            ? _handleDeliveryAction(context, _selectedDelivery!, action, token)
                            : null,
                      ),
                      sidebarBuilder: (isCollapsed) => UnifiedDeliveryListView(
                        deliveries: deliveries,
                        selectedDelivery: _selectedDelivery,
                        scrollController: _listScrollController,
                        onDeliverySelected: (delivery) {
                          setState(() {
                            _selectedDelivery = delivery;
                          });
                        },
                        onItemAction: (delivery, action) {
                          _handleDeliveryAction(context, delivery, action, token);
                          _autoScrollToFirstPending(deliveries);
                        },
                        isCollapsed: isCollapsed,
                      ),
                    );
            },
            loading: () => const Center(
              child: CircularProgressIndicator(),
            ),
            error: (error, stackTrace) => MapSidebarLayout(
              mapWidget: DarkModeMapComponent(
                deliveries: deliveries,
                selectedDelivery: _selectedDelivery,
                onDeliverySelected: (delivery) {
                  setState(() {
                    _selectedDelivery = delivery;
                  });
                },
                onAction: (action) => _selectedDelivery != null
                    ? _handleDeliveryAction(context, _selectedDelivery!, action, token)
                    : null,
              ),
              sidebarBuilder: (isCollapsed) => UnifiedDeliveryListView(
                deliveries: deliveries,
                selectedDelivery: _selectedDelivery,
                scrollController: _listScrollController,
                onDeliverySelected: (delivery) {
                  setState(() {
                    _selectedDelivery = delivery;
                  });
                },
                onItemAction: (delivery, action) {
                  _handleDeliveryAction(context, delivery, action, token);
                  _autoScrollToFirstPending(deliveries);
                },
                isCollapsed: isCollapsed,
              ),
            ),
          );
        },
        loading: () => const Center(
          child: CircularProgressIndicator(),
        ),
        error: (error, stackTrace) => Center(
          child: Text(l10n.error(error.toString())),
        ),
      ),
      ),
    );
  }

  Future<void> _handleDeliveryAction(
    BuildContext context,
    Delivery delivery,
    String action,
    String? token,
  ) async {
    // Prevent any actions on warehouse delivery except map navigation
    if (delivery.isWarehouseDelivery && action != 'map') {
      return;
    }

    if (token == null) {
      final l10n = AppLocalizations.of(context);
      ToastHelper.showError(context, l10n.authenticationRequired);
      return;
    }

    final authClient = CqrsApiClient(
      config: ApiClientConfig(
        baseUrl: ApiClientConfig.production.baseUrl,
        defaultHeaders: {'Authorization': 'Bearer $token'},
      ),
    );

    switch (action) {
      case 'complete':
        final result = await authClient.executeCommand(
          endpoint: 'completeDelivery',
          command: CompleteDeliveryCommand(
            deliveryId: delivery.id,
          ),
        );
        result.when(
          success: (_) {
            final l10n = AppLocalizations.of(context);
            // ignore: unused_result
            ref.refresh(deliveriesProvider(widget.routeFragmentId));
            // ignore: unused_result
            ref.refresh(deliveryRoutesProvider);
            ToastHelper.showSuccess(context, l10n.deliverySuccessful);
          },
          onError: (error) {
            final l10n = AppLocalizations.of(context);
            ToastHelper.showError(context, l10n.error(error.message));
          },
        );
        break;

      case 'uncomplete':
        final result = await authClient.executeCommand(
          endpoint: 'markDeliveryAsUncompleted',
          command: MarkDeliveryAsUncompletedCommand(deliveryId: delivery.id),
        );
        result.when(
          success: (_) {
            // ignore: unused_result
            ref.refresh(deliveriesProvider(widget.routeFragmentId));
            // ignore: unused_result
            ref.refresh(deliveryRoutesProvider);
            ToastHelper.showSuccess(context, 'Delivery marked as uncompleted');
          },
          onError: (error) {
            final l10n = AppLocalizations.of(context);
            ToastHelper.showError(context, l10n.error(error.message));
          },
        );
        break;

      case 'photo':
        await _handlePhotoCapture(context, delivery, token);
        break;

      case 'call':
        final contact = delivery.orders.isNotEmpty && delivery.orders.first.contact != null
            ? delivery.orders.first.contact
            : null;
        if (contact?.phoneNumber != null) {
          final Uri phoneUri = Uri(scheme: 'tel', path: contact!.phoneNumber);
          if (await canLaunchUrl(phoneUri)) {
            await launchUrl(phoneUri);
          }
        }
        break;

      case 'map':
        // Navigation is now handled in-app by the DeliveryMap component
        // Just ensure the delivery is selected
        break;
    }
  }

  Future<void> _handlePhotoCapture(
    BuildContext context,
    Delivery delivery,
    String? token,
  ) async {
    if (token == null) {
      final l10n = AppLocalizations.of(context);
      ToastHelper.showError(context, l10n.authenticationRequired);
      return;
    }

    final ImagePicker picker = ImagePicker();
    XFile? pickedFile;

    try {
      pickedFile = await picker.pickImage(
        source: ImageSource.camera,
        imageQuality: 85,
      );
    } catch (e) {
      if (context.mounted) {
        ToastHelper.showError(context, 'Camera error: $e');
      }
      return;
    }

    if (pickedFile == null) {
      return;
    }

    if (!context.mounted) return;

    final bool? confirmed = await PhotoCaptureDialog.show(
      context,
      imageFile: File(pickedFile.path),
      deliveryName: delivery.name,
    );

    if (confirmed != true) {
      return;
    }

    if (!context.mounted) return;

    final localizations = AppLocalizations.of(context);
    LoadingDialog.show(context, message: localizations.uploadingPhoto);

    try {
      final Uri uploadUrl = Uri.parse(
        '${ApiClientConfig.production.baseUrl}/api/delivery/uploadDeliveryPicture?deliveryId=${delivery.id}',
      );

      final http.MultipartRequest request = http.MultipartRequest('POST', uploadUrl);
      request.headers['Authorization'] = 'Bearer $token';
      request.files.add(await http.MultipartFile.fromPath('file', pickedFile.path));

      final http.StreamedResponse streamedResponse = await request.send();
      final http.Response response = await http.Response.fromStream(streamedResponse);

      if (context.mounted) {
        LoadingDialog.hide(context);
      }

      if (response.statusCode >= 200 && response.statusCode < 300) {
        if (context.mounted) {
          ToastHelper.showSuccess(context, 'Photo uploaded successfully');
        }
        // ignore: unused_result
        ref.refresh(deliveriesProvider(widget.routeFragmentId));
      } else {
        if (context.mounted) {
          ToastHelper.showError(context, 'Upload failed: ${response.statusCode}');
        }
      }
    } catch (e) {
      if (context.mounted) {
        LoadingDialog.hide(context);
        ToastHelper.showError(context, 'Upload error: $e');
      }
    }
  }
}
