import 'package:flutter/material.dart';
import 'app_state.dart';
import 'app_theme.dart';
import 'l10n/app_localizations.dart';
import 'l10n/localization_helpers.dart';
import 'services/websocket_service.dart';
import 'services/dart_mq.dart';
import 'services/chat_service.dart';
import 'models/delivery_station.dart';
import 'models/job.dart';
import 'models/task.dart';
import 'models/tasks/confirmation_task.dart';
import 'models/tasks/photo_task.dart';
import 'models/tasks/todolist_task.dart';
import 'models/tasks/signature_task.dart';
import 'models/tasks/barcode_task.dart';
import 'models/tasks/comment_task.dart';
import 'widgets/offline_banner.dart';
import 'package:votianlt_app/services/developer.dart' as developer;
import 'dart:async';
import 'services/database_service.dart';

import 'navigation_observer.dart';
import 'routing_view.dart';

class JobsView extends StatefulWidget {
  const JobsView({super.key});

  @override
  State<JobsView> createState() => _JobsViewState();
}

class _JobsViewState extends State<JobsView> with RouteAware {
  bool _routeActionInProgress = false;
  void _openRoutingView({
    required String address,
    required bool isDelivery,
    String? title,
  }) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder:
            (_) => RoutingView(
              address: address,
              isDelivery: isDelivery,
              title: title,
            ),
      ),
    );
  }

  final AppState _appState = AppState();
  final StompService _stompService = StompService();
  final ChatService _chatService = ChatService();

  bool _isLoadingDialogShowing = false;
  bool _isLoadingJobs = false;
  DartMQSubscription? _jobsSub;
  DartMQSubscription? _connectionSub;
  DartMQSubscription? _jobDeletedSub;
  DartMQSubscription? _jobCreatedSub;
  bool _wasConnected = false;
  bool _isLoggingOut = false;
  final DatabaseService _databaseService = DatabaseService();
  Map<String, bool> _taskStatuses = const {};
  Map<String, bool> _jobSeen = const {};
  Map<String, double> _jobSwipeOffsets = const {};
  String? _openJobId;
  static const double _jobSwipeRevealOffset = 50.0;
  final Set<String> _jobsBeingDeleted = <String>{};
  // Listen to AppState jobsUpdated to apply UI refresh exactly once
  StreamSubscription<void>? _jobsUpdatedSub;
  bool _isApplyingJobs = false;
  StreamSubscription<int>? _unreadCountSub;
  int _unreadMessageCount = 0;

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

    // Always load local task completion statuses to compute progress/card colors
    _loadLocalTaskStatuses();

    // Remember initial connection state
    _wasConnected = _stompService.isConnected;
    // Subscribe to route changes
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final route = ModalRoute.of(context);
      if (route != null) {
        routeObserver.subscribe(this, route);
      }
    });

    // Listen to connection changes to show banner (handled by widget) and trigger reloads
    _connectionSub = DartMQ().subscribe<bool>(MQTopics.connectionStatus, (
      isConnected,
    ) {
      // Went online
      if (isConnected && !_wasConnected) {
        _showSnack(
          AppLocalizations.of(context).connectionRestored,
          backgroundColor: AppColors.success,
        );
        if (_appState.isLoggedIn) {
          _loadJobs();
        }
      }

      // Went offline
      if (!isConnected && _wasConnected) {
        if (mounted && _isLoadingDialogShowing) {
          _isLoadingDialogShowing = false;
          Navigator.of(context, rootNavigator: true).pop();
        }
        // Only show offline message when user is logged in and not in logout flow
        if (_appState.isLoggedIn && !_isLoggingOut) {
          _showSnack(
            AppLocalizations.of(context).connectionLost,
            backgroundColor: AppColors.danger,
          );
        }
      }

      _wasConnected = isConnected;
    });

    // Listen to job deletion events from server
    _jobDeletedSub = DartMQ().subscribe<
      Map<String, dynamic>
    >(MQTopics.jobDeleted, (data) async {
      final jobId = data['jobId']?.toString();
      final jobNumber = data['jobNumber']?.toString();

      if (jobId == null) return;

      developer.log(
        'Job deleted event received: $jobId ($jobNumber)',
        name: 'JobsView',
      );

      // Delete job from AppState (which also updates DB and notifies listeners)
      await _appState.deleteJob(jobId);

      // Show notification to user
      if (mounted) {
        final message =
            jobNumber != null
                ? 'Job $jobNumber ${AppLocalizations.of(context).jobRemoved}'
                : AppLocalizations.of(context).jobRemoved;
        _showSnack(message, backgroundColor: AppColors.warning);
      }
    });

    // Listen to job creation events from server
    _jobCreatedSub = DartMQ().subscribe<
      Map<String, dynamic>
    >(MQTopics.jobCreated, (data) async {
      developer.log('Job created event received', name: 'JobsView');

      try {
        // WICHTIG: Der Job wurde bereits vom WebSocketService übersetzt und in die DB gespeichert.
        // Wir laden die Jobs aus der Datenbank neu, um die übersetzte Version anzuzeigen.
        developer.log(
          'Reloading jobs from database to get translated version...',
          name: 'JobsView',
        );
        await _loadJobsFromDatabase();

        // Extract job number for notification
        final jobNumber =
            data['job']?['jobNumber']?.toString() ??
            data['jobNumber']?.toString() ??
            '';

        // Show notification to user
        if (mounted) {
          final message =
              jobNumber.isNotEmpty
                  ? '${AppLocalizations.of(context).newJobReceived}: $jobNumber'
                  : AppLocalizations.of(context).newJobReceived;
          _showSnack(message, backgroundColor: AppColors.success);
        }
      } catch (e) {
        developer.log('Error handling job_created event: $e', name: 'JobsView');
      }
    });

    // Listen once-per-cycle for jobs updates from AppState
    _jobsUpdatedSub = _appState.jobsUpdated.listen((_) async {
      if (_isApplyingJobs) {
        return;
      }
      _isApplyingJobs = true;
      try {
        await _appState.refreshJobsFromDatabase();
        await _loadLocalTaskStatuses();
        await _loadSeenFlagsForCurrentJobs();
        if (mounted && _isLoadingDialogShowing) {
          _isLoadingDialogShowing = false;
          Navigator.of(context, rootNavigator: true).pop();
        }
        if (mounted) {
          setState(() {
            _syncSwipeStateWithJobs();
          });
          _showSnack(
            AppLocalizations.of(context).jobsUpdated,
            backgroundColor: AppColors.success,
          );
        }
      } finally {
        _isApplyingJobs = false;
      }
    });

    // Listen to unread message count changes
    _unreadCountSub = _chatService.unreadCountStream.listen((count) {
      developer.log(
        '[DEBUG_LOG] JobsView received unread count from stream: $count',
        name: 'JobsView',
      );
      if (mounted) {
        setState(() {
          _unreadMessageCount = count;
        });
        developer.log(
          '[DEBUG_LOG] JobsView updated badge with count: $_unreadMessageCount',
          name: 'JobsView',
        );
      }
    });

    // Initialize chat service and get initial unread count
    _chatService.initialize().then((_) {
      developer.log(
        '[DEBUG_LOG] ChatService initialized, initial unread count: ${_chatService.unreadCount}',
        name: 'JobsView',
      );
      if (mounted) {
        setState(() {
          _unreadMessageCount = _chatService.unreadCount;
        });
        developer.log(
          '[DEBUG_LOG] JobsView set initial badge count to: $_unreadMessageCount',
          name: 'JobsView',
        );
      }
    });

    // Load jobs from database first (for offline/cached jobs)
    _loadJobsFromDatabase();

    _initializeAndLoadJobs();
    // Also load seen flags for any jobs already in memory (e.g., from DB)
    _loadSeenFlagsForCurrentJobs();
  }

  /// Load jobs from database on startup
  Future<void> _loadJobsFromDatabase() async {
    try {
      developer.log(
        'Loading jobs from database on startup...',
        name: 'JobsView',
      );
      await _appState.refreshJobsFromDatabase();
      await _loadLocalTaskStatuses();
      await _loadSeenFlagsForCurrentJobs();
      if (mounted) {
        setState(() {
          _syncSwipeStateWithJobs();
        });
        developer.log(
          'Jobs loaded from database: ${_appState.assignedJobs.length}',
          name: 'JobsView',
        );

        // Debug: Log each job loaded from database
        for (int i = 0; i < _appState.assignedJobs.length; i++) {
          final job = _appState.assignedJobs[i];
          developer.log(
            'DB Job $i: ${job.jobNumber} (${job.id}) - Tasks: ${job.tasks.length}, CargoItems: ${job.cargoItems.length}',
            name: 'JobsView',
          );
        }
      }
    } catch (e, stackTrace) {
      developer.log('Error loading jobs from database: $e', name: 'JobsView');
      developer.log('Stack trace: $stackTrace', name: 'JobsView');
    }
  }

  /// Initialize connection and load jobs
  Future<void> _initializeAndLoadJobs() async {
    // Only proceed if user is logged in
    if (!_appState.isLoggedIn) {
      developer.log(
        'Skip jobs initialization: user not logged in',
        name: 'JobsView',
      );
      return;
    }

    try {
      // If not connected and authenticated, initiate connection and wait
      final isFullyConnected =
          _stompService.isConnected && _stompService.isAuthenticated;
      if (!isFullyConnected) {
        developer.log(
          'No authenticated connection at jobs load time - initiating connection',
          name: 'JobsView',
        );

        // Show loading dialog while waiting for connection
        if (mounted && !_isLoadingDialogShowing) {
          WidgetsBinding.instance.addPostFrameCallback((_) {
            if (mounted && !_isLoadingDialogShowing) {
              _showLoadingDialog();
            }
          });
        }

        // Initiate WebSocket connection (will auto-login with saved credentials)
        // connect() is safe to call multiple times - it prevents overlapping attempts
        _stompService.connect();

        // Wait for connection and authentication with timeout
        await _waitForConnection();
      }

      // Show loading dialog if not already shown and we're fully connected
      final isNowFullyConnected =
          _stompService.isConnected && _stompService.isAuthenticated;
      if (mounted && !_isLoadingDialogShowing && isNowFullyConnected) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          final stillFullyConnected =
              _stompService.isConnected && _stompService.isAuthenticated;
          if (mounted && !_isLoadingDialogShowing && stillFullyConnected) {
            _showLoadingDialog();
          }
        });
      }

      // Load jobs only if connected AND authenticated
      if (_stompService.isConnected && _stompService.isAuthenticated) {
        await _loadJobs();
      } else {
        _showSnack(
          'Verbindung zum Server konnte nicht hergestellt werden.',
          backgroundColor: Colors.red,
        );
      }
    } catch (e) {
      developer.log('Error during initialization: $e', name: 'JobsView');
    }

    // Reset loading flag after attempt (no dialog to close)
    if (mounted && _isLoadingDialogShowing) {
      _isLoadingDialogShowing = false;
    }
  }

  /// Wait for WebSocket connection and authentication to be established
  Future<void> _waitForConnection() async {
    // If already connected and authenticated, return immediately
    if (_stompService.isConnected && _stompService.isAuthenticated) {
      return;
    }

    final completer = Completer<void>();

    // Listen for connection status changes
    final connectionSub = DartMQ().subscribe<bool>(MQTopics.connectionStatus, (
      isConnected,
    ) {
      if (isConnected && !completer.isCompleted) {
        completer.complete();
      }
    });

    try {
      // Wait with timeout (30 seconds)
      await completer.future.timeout(const Duration(seconds: 30));
    } catch (e) {
      developer.log('Connection wait timeout or error: $e', name: 'JobsView');
    } finally {
      // Cancel subscription after completer resolves or times out
      connectionSub.cancel();
    }
  }

  /// Preload task statuses (no dialog shown)
  void _showLoadingDialog() {
    _isLoadingDialogShowing = true;
    // Preload task statuses to compute card colors
    _databaseService.loadAllTaskStatuses().then((map) {
      if (!mounted) return;
      setState(() {
        _taskStatuses = map;
      });
    });
    // Dialog removed - loading happens silently in background
  }

  /// Load jobs from server
  Future<void> _loadJobs() async {
    if (!_appState.isLoggedIn) {
      developer.log('Not logged in - cannot load jobs', name: 'JobsView');
      return;
    }

    if (_isLoadingJobs) {
      developer.log(
        'Load jobs already in progress - skipping',
        name: 'JobsView',
      );
      return;
    }

    _isLoadingJobs = true;

    final completer = Completer<void>();

    try {
      developer.log('Loading jobs...', name: 'JobsView');

      // Listen for first jobs response only
      _jobsSub?.cancel();
      _jobsSub = DartMQ().subscribe<List<dynamic>>(MQTopics.jobsResponse, (
        jobsData,
      ) async {
        if (!mounted) return;

        final List<dynamic> list = jobsData;
        developer.log(
          'Jobs response received: ${list.length} jobs',
          name: 'JobsView',
        );

        // WICHTIG: Die Jobs wurden bereits vom WebSocketService übersetzt und in die DB gespeichert.
        // Wir laden die Jobs aus der Datenbank, um die übersetzten Versionen zu erhalten.
        developer.log(
          'Loading translated jobs from database...',
          name: 'JobsView',
        );
        await _loadJobsFromDatabase();

        // Complete and cancel subscription
        if (!completer.isCompleted) {
          completer.complete();
        }
        _jobsSub?.cancel();
        _jobsSub = null;
        _isLoadingJobs = false;
      });
    } catch (e) {
      developer.log('Error loading jobs: $e', name: 'JobsView');
      if (mounted && _isLoadingDialogShowing) {
        _isLoadingDialogShowing = false;
      }
      _isLoadingJobs = false;
    }
  }

  // Helper to show SnackBars safely (not during initState)
  void _showSnack(String message, {Color? backgroundColor}) {
    if (!mounted) return;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;
      final messenger = ScaffoldMessenger.maybeOf(context);
      messenger?.showSnackBar(
        SnackBar(
          content: Text(message),
          backgroundColor: backgroundColor,
          duration: const Duration(seconds: 1),
        ),
      );
    });
  }

  Future<void> _loadLocalTaskStatuses() async {
    final map = await _databaseService.loadAllTaskStatuses();
    if (!mounted) return;
    setState(() {
      _taskStatuses = map;
    });
  }

  Future<void> _loadSeenFlagsForCurrentJobs() async {
    final jobs = _appState.assignedJobs;
    if (jobs.isEmpty) return;
    final ids = jobs.map((j) => j.id).toSet();
    final seenMap = await _databaseService.loadSeenJobsForIds(ids);
    if (!mounted) return;
    setState(() {
      _jobSeen = seenMap;
    });
  }

  String _two(int n) => n.toString().padLeft(2, '0');

  String _formatDateString(String dateStr) {
    // Convert "YYYY-MM-DD" to "DD.MM.YYYY"
    if (dateStr.isEmpty) return '';
    final parts = dateStr.split('-');
    if (parts.length == 3) {
      return '${parts[2]}.${parts[1]}.${parts[0]}';
    }
    return dateStr;
  }

  String _formatTimeString(String timeStr) {
    // Convert "HH:MM:SS" to "HH:MM"
    if (timeStr.isEmpty) return '';
    final parts = timeStr.split(':');
    if (parts.length >= 2) {
      return '${parts[0]}:${parts[1]}';
    }
    return timeStr;
  }

  String _formatDate(DateTime dt) {
    // Format: dd.MM.yyyy HH:mm
    return '${_two(dt.day)}.${_two(dt.month)}.${dt.year} ${_two(dt.hour)}:${_two(dt.minute)}';
  }

  String _joinNonEmpty(List<String> parts, {String sep = ' '}) =>
      parts.where((p) => p.trim().isNotEmpty).join(sep);

  @override
  void didPopNext() {
    // Called when returning to this route from another route (e.g., TaskView)
    // Reload local task statuses so progress and card colors reflect changes
    _loadLocalTaskStatuses();
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    _jobsSub?.cancel();
    _jobsSub = null;
    _jobsUpdatedSub?.cancel();
    _jobsUpdatedSub = null;
    _unreadCountSub?.cancel();
    _unreadCountSub = null;
    _connectionSub?.cancel();
    _connectionSub = null;
    _jobDeletedSub?.cancel();
    _jobDeletedSub = null;
    _jobCreatedSub?.cancel();
    _jobCreatedSub = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        PopScope(
          canPop: false,
          child: Scaffold(
            appBar: AppBar(
              automaticallyImplyLeading: false,
              title: Text(AppLocalizations.of(context).availableJobs),
              leading: IconButton(
                icon: const Icon(Icons.logout),
                onPressed: () {
                  _handleLogout();
                },
                tooltip: AppLocalizations.of(context).logout,
              ),
              actions: [
                // Chat Icon with Badge
                Padding(
                  padding: const EdgeInsets.only(right: 4.0),
                  child: Badge(
                    label: Text('$_unreadMessageCount'),
                    isLabelVisible: _unreadMessageCount > 0,
                    child: IconButton(
                      icon: const Icon(Icons.chat),
                      onPressed: () {
                        Navigator.of(context).pushNamed('/chats');
                      },
                      tooltip: AppLocalizations.of(context).openChat,
                    ),
                  ),
                ),
                // Settings Icon
                Padding(
                  padding: const EdgeInsets.only(right: 10.0),
                  child: IconButton(
                    icon: const Icon(Icons.settings),
                    onPressed: () {
                      Navigator.of(context).pushNamed('/settings');
                    },
                    tooltip: AppLocalizations.of(context).settings,
                  ),
                ),
              ],
            ),
            body: Column(
              children: [
                // Offline banner under header
                OfflineBanner(),

                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [Expanded(child: _buildJobsList())],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  void _handleLogout() {
    // Capture a parent context before opening the dialog to ensure we can always navigate on root
    final parentContext = context;
    showDialog(
      context: parentContext,
      builder: (BuildContext dialogContext) {
        return AlertDialog(
          title: Text(AppLocalizations.of(context).logoutConfirm),
          content: Text(AppLocalizations.of(context).logoutConfirmMessage),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(dialogContext).pop();
              },
              child: Text(AppLocalizations.of(context).cancel),
            ),
            ElevatedButton(
              onPressed: () async {
                _isLoggingOut = true; // suppress connection snackbars

                // We'll ensure navigation to login in a finally block
                try {
                  await _appState.clearLogin(); // clear login + DB
                  await _stompService
                      .logout(); // only clear auth state, keep WebSocket connected

                  // Cleanup
                  _jobsSub?.cancel();
                  _jobsSub = null;

                  // Prevent further job loads until next login
                  _wasConnected = false;
                } catch (e, stackTrace) {
                  developer.log(
                    'Error during logout flow: $e',
                    name: 'JobsView',
                  );
                  developer.log('Stack trace: $stackTrace', name: 'JobsView');
                } finally {
                  if (!mounted) {
                    // If the widget is already unmounted, we cannot navigate here safely.
                    // Navigation to login will be handled by higher-level route guards on next build.
                  } else {
                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      if (!mounted) {
                        return;
                      }

                      // Use the parentContext to get the root navigator (avoid dialog context pitfalls)
                      final rootNav = Navigator.of(
                        parentContext,
                        rootNavigator: true,
                      );

                      // Clear any visible SnackBars before navigation
                      ScaffoldMessenger.maybeOf(
                        parentContext,
                      )?.clearSnackBars();

                      // Close any remaining routes above root (e.g., dialogs)
                      while (rootNav.canPop()) {
                        rootNav.pop();
                      }

                      // Navigate to login, clearing stack and suppressing connection snack
                      rootNav.pushNamedAndRemoveUntil(
                        '/login',
                        (route) => false,
                        arguments: true, // suppressConnectionSnack
                      );
                    });
                  }
                }
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.danger,
                foregroundColor: Colors.white,
              ),
              child: Text(AppLocalizations.of(context).logout),
            ),
          ],
        );
      },
    );
  }

  Widget _buildJobsList() {
    final jobs = List<Job>.from(_appState.assignedJobs)..sort((a, b) {
      final aSeen = _jobSeen[a.id] ?? false;
      final bSeen = _jobSeen[b.id] ?? false;
      if (aSeen != bSeen) {
        // Unseen first
        return aSeen ? 1 : -1;
      }
      // Then by time (oldest first within each group)
      return a.createdAt.compareTo(b.createdAt);
    });

    return RefreshIndicator(
      onRefresh: _refreshJobs,
      child:
          jobs.isEmpty
              ? ListView(
                children: [
                  SizedBox(
                    height: MediaQuery.of(context).size.height * 0.6,
                    child: Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            Icons.work_outline,
                            size: 64,
                            color: Colors.grey[400],
                          ),
                          const SizedBox(height: 16),
                          Text(
                            AppLocalizations.of(context).noJobsAssigned,
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.grey[600],
                            ),
                          ),
                          const SizedBox(height: 8),
                          Text(
                            AppLocalizations.of(context).noJobsMessage,
                            style: TextStyle(
                              fontSize: 14,
                              color: Colors.grey[500],
                            ),
                            textAlign: TextAlign.center,
                          ),
                          const SizedBox(height: 8),
                          Text(
                            AppLocalizations.of(context).pullToRefresh,
                            style: TextStyle(
                              fontSize: 12,
                              color: Colors.grey[400],
                            ),
                            textAlign: TextAlign.center,
                          ),
                          const SizedBox(height: 16),
                          ElevatedButton.icon(
                            onPressed: _refreshJobs,
                            icon: const Icon(Icons.refresh),
                            label: Text(AppLocalizations.of(context).refresh),
                            style: ElevatedButton.styleFrom(
                              backgroundColor: AppColors.primarySoft,
                              foregroundColor: AppColors.primaryStrong,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              )
              : ListView.builder(
                itemCount: jobs.length,
                itemBuilder: (context, index) {
                  final job = jobs[index];
                  return _buildJobCard(job);
                },
              ),
    );
  }

  Future<void> _refreshJobs() async {
    if (_stompService.isConnected && _stompService.isAuthenticated) {
      await _loadJobs();
    } else {
      _showSnack(
        AppLocalizations.of(context).offline,
        backgroundColor: AppColors.danger,
      );
    }
  }

  void _syncSwipeStateWithJobs() {
    final jobIds = _appState.assignedJobs.map((job) => job.id).toSet();
    final updatedOffsets = <String, double>{};
    _jobSwipeOffsets.forEach((jobId, offset) {
      if (jobIds.contains(jobId) && offset != 0) {
        updatedOffsets[jobId] = offset;
      }
    });
    _jobSwipeOffsets = updatedOffsets;
    if (_openJobId != null && !jobIds.contains(_openJobId)) {
      _openJobId = null;
    }
  }

  void _handleJobDragUpdate(Job job, DragUpdateDetails details) {
    final current = _jobSwipeOffsets[job.id] ?? 0.0;
    var next = current + details.delta.dx;
    if (next < -_jobSwipeRevealOffset) {
      next = -_jobSwipeRevealOffset;
    }
    if (next > 0) {
      next = 0;
    }
    if ((next - current).abs() < 0.5) {
      return;
    }
    setState(() {
      final updated = Map<String, double>.from(_jobSwipeOffsets);
      if (next == 0) {
        updated.remove(job.id);
      } else {
        updated[job.id] = next;
      }
      _jobSwipeOffsets = updated;
    });
  }

  void _handleJobDragEnd(Job job, DragEndDetails details) {
    final current = _jobSwipeOffsets[job.id] ?? 0.0;
    final velocity = details.primaryVelocity ?? 0.0;
    final shouldOpen =
        current <= -(_jobSwipeRevealOffset / 2) || velocity < -300;
    setState(() {
      final updated = Map<String, double>.from(_jobSwipeOffsets);
      if (shouldOpen) {
        updated
          ..clear()
          ..[job.id] = -_jobSwipeRevealOffset;
        _jobSwipeOffsets = updated;
        _openJobId = job.id;
      } else {
        updated.remove(job.id);
        _jobSwipeOffsets = updated;
        if (_openJobId == job.id) {
          _openJobId = null;
        }
      }
    });
  }

  void _closeSwipe(String jobId) {
    final current = _jobSwipeOffsets[jobId] ?? 0.0;
    if (current == 0 && _openJobId != jobId) {
      return;
    }
    setState(() {
      final updated = Map<String, double>.from(_jobSwipeOffsets)..remove(jobId);
      _jobSwipeOffsets = updated;
      if (_openJobId == jobId) {
        _openJobId = null;
      }
    });
  }

  Future<void> _deleteJob(Job job) async {
    final jobId = job.id;
    if (_jobsBeingDeleted.contains(jobId)) {
      return;
    }

    setState(() {
      _jobsBeingDeleted.add(jobId);
    });

    _closeSwipe(jobId);

    try {
      await _databaseService.deleteJobAndRelatedData(job);
      _appState.removeJob(jobId);

      final updatedStatuses = Map<String, bool>.from(
        _taskStatuses,
      )..removeWhere((taskId, _) => job.tasks.any((task) => task.id == taskId));
      final updatedSeen = Map<String, bool>.from(_jobSeen)..remove(jobId);

      if (mounted) {
        setState(() {
          _taskStatuses = updatedStatuses;
          _jobSeen = updatedSeen;
          _syncSwipeStateWithJobs();
        });
      }

      await _chatService.deleteJobChats(
        jobId,
        jobNumber: job.jobNumber.trim().isEmpty ? null : job.jobNumber,
      );

      if (mounted) {
        _showSnack(
          AppLocalizations.of(context).jobDeleted,
          backgroundColor: AppColors.danger,
        );
      }
    } catch (e, st) {
      developer.log('Error deleting job $jobId: $e', name: 'JobsView');
      developer.log('Stack trace: $st', name: 'JobsView');
      if (mounted) {
        _showSnack(
          AppLocalizations.of(context).jobDeleteError,
          backgroundColor: AppColors.danger,
        );
      }
    } finally {
      if (mounted) {
        setState(() {
          _jobsBeingDeleted.remove(jobId);
        });
      } else {
        _jobsBeingDeleted.remove(jobId);
      }
    }
  }

  Widget _buildJobCard(Job job) {
    Color statusColor;
    switch (job.statusColor) {
      case 'green':
        statusColor = AppColors.success;
        break;
      case 'blue':
        statusColor = AppColors.primary;
        break;
      case 'orange':
        statusColor = AppColors.warning;
        break;
      case 'red':
        statusColor = AppColors.danger;
        break;
      default:
        statusColor = AppColors.textMuted;
    }

    // Determine card background color based on task completion
    final totalTasks = job.tasks.length;
    int completedTasks = 0;
    for (final t in job.tasks) {
      final isCompleted = _taskStatuses[t.id] ?? t.completed;
      if (isCompleted) completedTasks++;
    }

    // Check if all tasks are completed (job is done)
    final bool isJobCompleted = totalTasks > 0 && completedTasks == totalTasks;

    Color? cardBg;
    if (totalTasks == 0 || completedTasks == 0) {
      cardBg = null; // unchanged (default)
    } else if (completedTasks > 0 && completedTasks < totalTasks) {
      cardBg = AppColors.warningSoft;
    } else if (completedTasks == totalTasks) {
      cardBg = AppColors.successSoft;
    }
    // Build robust display strings with fallbacks
    final pickupName = _joinNonEmpty([job.pickupFirstName, job.pickupLastName]);
    final pickupDisplayName =
        pickupName.isNotEmpty ? pickupName : job.pickupCompany;
    final pickupAddress = _joinNonEmpty([
      _joinNonEmpty([job.pickupStreet, job.pickupHouseNumber]),
      _joinNonEmpty([job.pickupZip, job.pickupCity]),
    ], sep: ', ');

    final deliveryName = _joinNonEmpty([
      job.deliveryFirstName,
      job.deliveryLastName,
    ]);
    final firstDeliveryStation =
        job.deliveryStations.isNotEmpty ? job.deliveryStations.first : null;
    final hasMultipleDeliveryStations = job.deliveryStations.length > 1;
    final deliveryDisplayName =
        hasMultipleDeliveryStations
            ? (job.deliveryCitiesDisplay.isNotEmpty
                ? job.deliveryCitiesDisplay
                : job.deliveryCompany)
            : (deliveryName.isNotEmpty
                ? deliveryName
                : (firstDeliveryStation?.displayName.isNotEmpty == true
                    ? firstDeliveryStation!.displayName
                    : job.deliveryCompany));
    final deliveryAddress =
        hasMultipleDeliveryStations
            ? AppLocalizations.of(
              context,
            ).deliveryStationsCount(job.deliveryStations.length)
            : (firstDeliveryStation?.formattedAddress.isNotEmpty == true
                ? firstDeliveryStation!.formattedAddress
                : _joinNonEmpty([
                  _joinNonEmpty([job.deliveryStreet, job.deliveryHouseNumber]),
                  _joinNonEmpty([job.deliveryZip, job.deliveryCity]),
                ], sep: ', '));
    final deliveryRouteAddress =
        firstDeliveryStation?.formattedAddress.isNotEmpty == true
            ? firstDeliveryStation!.formattedAddress
            : deliveryAddress;

    final swipeOffset = _jobSwipeOffsets[job.id] ?? 0.0;
    final isDeleting = _jobsBeingDeleted.contains(job.id);

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      child: Stack(
        children: [
          Positioned.fill(
            child: Align(
              alignment: Alignment.centerRight,
              child: IgnorePointer(
                ignoring: swipeOffset == 0,
                child: AnimatedOpacity(
                  opacity: (swipeOffset.abs() / _jobSwipeRevealOffset).clamp(
                    0,
                    1,
                  ),
                  duration: const Duration(milliseconds: 150),
                  child: IconButton(
                    iconSize: 28,
                    padding: const EdgeInsets.all(10),
                    splashRadius: 24,
                    icon: const Icon(Icons.delete, color: AppColors.danger),
                    tooltip: AppLocalizations.of(context).deleteJob,
                    onPressed: () {
                      if (isDeleting) {
                        return;
                      }
                      _deleteJob(job);
                    },
                  ),
                ),
              ),
            ),
          ),
          GestureDetector(
            // Only enable swipe gestures for completed jobs
            onHorizontalDragStart:
                isJobCompleted
                    ? (_) {
                      final openId = _openJobId;
                      if (openId != null && openId != job.id) {
                        _closeSwipe(openId);
                      }
                    }
                    : null,
            onHorizontalDragUpdate:
                isJobCompleted
                    ? (details) {
                      if (_jobsBeingDeleted.contains(job.id)) {
                        return;
                      }
                      _handleJobDragUpdate(job, details);
                    }
                    : null,
            onHorizontalDragEnd:
                isJobCompleted
                    ? (details) {
                      if (_jobsBeingDeleted.contains(job.id)) {
                        return;
                      }
                      _handleJobDragEnd(job, details);
                    }
                    : null,
            onHorizontalDragCancel:
                isJobCompleted ? () => _closeSwipe(job.id) : null,
            child: TweenAnimationBuilder<double>(
              tween: Tween<double>(begin: 0, end: swipeOffset),
              duration: const Duration(milliseconds: 150),
              curve: Curves.easeOut,
              builder: (context, value, child) {
                return Transform.translate(
                  offset: Offset(value, 0),
                  child: child,
                );
              },
              child: Card(
                margin: EdgeInsets.zero,
                elevation: 2,
                color: cardBg,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
                clipBehavior: Clip.antiAlias,
                child: InkWell(
                  onTap: () {
                    final isOpen = (_jobSwipeOffsets[job.id] ?? 0) != 0;
                    if (isOpen) {
                      _closeSwipe(job.id);
                      return;
                    }
                    _showJobDetails(job);
                  },
                  borderRadius: BorderRadius.circular(8),
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    job.jobNumber.isNotEmpty
                                        ? job.jobNumber
                                        : localizeKnownText(context, job.title),
                                    style: const TextStyle(
                                      fontSize: 16,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                  if (job.customerSelection.isNotEmpty) ...[
                                    const SizedBox(height: 2),
                                    Text(
                                      job.customerSelection,
                                      style: TextStyle(
                                        fontSize: 14,
                                        color: Colors.grey[700],
                                        fontWeight: FontWeight.w500,
                                      ),
                                    ),
                                  ],
                                  if (job.customerSelection.isEmpty &&
                                      (job.pickupCity.isNotEmpty ||
                                          job.deliveryCity.isNotEmpty)) ...[
                                    const SizedBox(height: 2),
                                    Text(
                                      '${AppLocalizations.of(context).from} ${job.pickupCity.isNotEmpty ? job.pickupCity : '?'} ${AppLocalizations.of(context).to} ${job.deliveryCity.isNotEmpty ? job.deliveryCity : '?'}',
                                      style: TextStyle(
                                        fontSize: 13,
                                        color: Colors.grey[700],
                                      ),
                                    ),
                                  ],
                                  if (job.customerSelection.isEmpty &&
                                      job.pickupCity.isEmpty &&
                                      job.deliveryCity.isEmpty &&
                                      job.description.isNotEmpty) ...[
                                    const SizedBox(height: 2),
                                    Text(
                                      job.description,
                                      style: TextStyle(
                                        fontSize: 13,
                                        color: Colors.grey[700],
                                      ),
                                      maxLines: 2,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                  ],
                                ],
                              ),
                            ),
                            Builder(
                              builder: (_) {
                                final seen = _jobSeen[job.id] ?? false;
                                if (!seen) {
                                  // Fire and forget DB write; do not block build
                                  _databaseService.setJobSeen(job.id).then((
                                    _,
                                  ) async {
                                    if (mounted) {
                                      setState(() {
                                        _jobSeen = Map<String, bool>.from(
                                          _jobSeen,
                                        )..[job.id] = true;
                                      });
                                    }
                                  });
                                }
                                if (seen) {
                                  return const SizedBox.shrink();
                                }
                                return Container(
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 8,
                                    vertical: 4,
                                  ),
                                  decoration: BoxDecoration(
                                    color: statusColor.withValues(alpha: 0.1),
                                    borderRadius: BorderRadius.circular(12),
                                    border: Border.all(
                                      color: statusColor.withValues(alpha: 0.3),
                                    ),
                                  ),
                                  child: Text(
                                    AppLocalizations.of(context).newLabel,
                                    style: TextStyle(
                                      fontSize: 12,
                                      color: statusColor.withValues(alpha: 0.8),
                                      fontWeight: FontWeight.w500,
                                    ),
                                  ),
                                );
                              },
                            ),
                          ],
                        ),
                        // Progress bar for tasks
                        if (totalTasks > 0) ...[
                          const SizedBox(height: 8),
                          Text(
                            AppLocalizations.of(context).tasksToComplete,
                            style: TextStyle(
                              fontSize: 12,
                              color: Colors.grey[500],
                            ),
                          ),
                          const SizedBox(height: 4),
                          Row(
                            children: [
                              Expanded(
                                child: ClipRRect(
                                  borderRadius: BorderRadius.circular(6),
                                  child: LinearProgressIndicator(
                                    value:
                                        totalTasks == 0
                                            ? 0
                                            : completedTasks / totalTasks,
                                    minHeight: 8,
                                    backgroundColor: AppColors.border,
                                    valueColor: AlwaysStoppedAnimation<Color>(
                                      completedTasks >= totalTasks
                                          ? AppColors.success
                                          : (completedTasks > 0
                                              ? AppColors.warning
                                              : AppColors.primary),
                                    ),
                                  ),
                                ),
                              ),
                              const SizedBox(width: 8),
                              Text(
                                '$completedTasks/$totalTasks',
                                style: TextStyle(
                                  fontSize: 12,
                                  color: Colors.grey[700],
                                ),
                              ),
                            ],
                          ),
                        ],
                        const SizedBox(height: 12),
                        // Pickup Information
                        Row(
                          children: [
                            Icon(
                              Icons.arrow_upward,
                              size: 16,
                              color: Colors.green[600],
                            ),
                            const SizedBox(width: 4),
                            Text(
                              '${AppLocalizations.of(context).pickup}${job.pickupDate.isNotEmpty ? ' ${_formatDateString(job.pickupDate)}${job.pickupTime.isNotEmpty ? ' ${_formatTimeString(job.pickupTime)}' : ''}' : ''}',
                              style: TextStyle(
                                fontSize: 12,
                                color: Colors.grey[700],
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 2),
                        if (pickupDisplayName.isNotEmpty)
                          Text(
                            pickupDisplayName,
                            style: TextStyle(
                              fontSize: 13,
                              color: Colors.grey[800],
                            ),
                          ),
                        if (pickupAddress.isNotEmpty)
                          Row(
                            children: [
                              Expanded(
                                child: Text(
                                  pickupAddress,
                                  style: TextStyle(
                                    fontSize: 12,
                                    color: Colors.grey[600],
                                  ),
                                ),
                              ),
                              const SizedBox(width: 8),
                              IconButton(
                                tooltip: AppLocalizations.of(context).routePlan,
                                icon: const Icon(
                                  Icons.route,
                                  color: Colors.green,
                                ),
                                onPressed: () {
                                  if (_routeActionInProgress) return;
                                  setState(() => _routeActionInProgress = true);
                                  _openRoutingView(
                                    address: pickupAddress,
                                    isDelivery: false,
                                    title:
                                        pickupDisplayName.isNotEmpty
                                            ? 'Abholung$pickupDisplayName'
                                            : 'Abholadresse',
                                  );
                                  // Reset after short delay to avoid double-push
                                  Future.delayed(
                                    const Duration(milliseconds: 600),
                                    () {
                                      if (mounted) {
                                        setState(
                                          () => _routeActionInProgress = false,
                                        );
                                      }
                                    },
                                  );
                                },
                              ),
                            ],
                          ),
                        const SizedBox(height: 8),
                        // Delivery Information
                        Row(
                          children: [
                            Icon(
                              Icons.arrow_downward,
                              size: 16,
                              color: AppColors.primary,
                            ),
                            const SizedBox(width: 4),
                            Text(
                              '${AppLocalizations.of(context).delivery}${job.deliveryDate.isNotEmpty ? ' ${_formatDateString(job.deliveryDate)}${job.deliveryTime.isNotEmpty ? ' ${_formatTimeString(job.deliveryTime)}' : ''}' : ''}',
                              style: TextStyle(
                                fontSize: 12,
                                color: Colors.grey[700],
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 2),
                        if (deliveryDisplayName.isNotEmpty)
                          Text(
                            deliveryDisplayName,
                            style: TextStyle(
                              fontSize: 13,
                              color: Colors.grey[800],
                            ),
                          ),
                        if (deliveryAddress.isNotEmpty)
                          Row(
                            children: [
                              Expanded(
                                child: Text(
                                  deliveryAddress,
                                  style: TextStyle(
                                    fontSize: 12,
                                    color: Colors.grey[600],
                                  ),
                                ),
                              ),
                              const SizedBox(width: 8),
                              IconButton(
                                tooltip: 'Route planen',
                                icon: const Icon(
                                  Icons.route,
                                  color: AppColors.primary,
                                ),
                                onPressed: () {
                                  if (_routeActionInProgress) return;
                                  setState(() => _routeActionInProgress = true);
                                  _openRoutingView(
                                    address: deliveryRouteAddress,
                                    isDelivery: true,
                                    title:
                                        hasMultipleDeliveryStations
                                            ? 'Erste Zustelladresse'
                                            : (deliveryDisplayName.isNotEmpty
                                                ? 'Zustellung $deliveryDisplayName'
                                                : 'Zustelladresse'),
                                  );
                                  // Reset after short delay to avoid double-push
                                  Future.delayed(
                                    const Duration(milliseconds: 600),
                                    () {
                                      if (mounted) {
                                        setState(
                                          () => _routeActionInProgress = false,
                                        );
                                      }
                                    },
                                  );
                                },
                              ),
                            ],
                          ),
                        const SizedBox(height: 8),
                        // Dates and Price
                        Row(
                          children: [
                            Expanded(
                              child: Row(
                                children: [
                                  Icon(
                                    Icons.schedule,
                                    size: 16,
                                    color: Colors.grey[500],
                                  ),
                                  const SizedBox(width: 4),
                                  Text(
                                    '${AppLocalizations.of(context).created}: ${_formatDate(job.createdAt)}',
                                    style: TextStyle(
                                      fontSize: 12,
                                      color: Colors.grey[500],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            if (job.price > 0) ...[
                              Container(
                                padding: const EdgeInsets.symmetric(
                                  horizontal: 6,
                                  vertical: 2,
                                ),
                                decoration: BoxDecoration(
                                  color: Colors.green[50],
                                  borderRadius: BorderRadius.circular(8),
                                  border: Border.all(color: Colors.green[200]!),
                                ),
                                child: Text(
                                  '${job.price.toStringAsFixed(2)} €',
                                  style: TextStyle(
                                    fontSize: 12,
                                    color: Colors.green[700],
                                    fontWeight: FontWeight.w600,
                                  ),
                                ),
                              ),
                            ],
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  void _showJobDetails(Job job) {
    Navigator.of(context).pushNamed('/cargo_items', arguments: job);
  }

  void _toggleTaskCompletion(Job job, int taskIndex) {
    // Create a new task with toggled completion status
    final updatedTask = job.tasks[taskIndex].copyWith(
      completed: !job.tasks[taskIndex].completed,
    );

    // Create a new list with the updated task
    final updatedTasks = List<Task>.from(job.tasks);
    updatedTasks[taskIndex] = updatedTask;
    final updatedDeliveryStations =
        job.deliveryStations
            .map(
              (station) => DeliveryStation(
                stationOrder: station.stationOrder,
                company: station.company,
                salutation: station.salutation,
                firstName: station.firstName,
                lastName: station.lastName,
                phone: station.phone,
                street: station.street,
                houseNumber: station.houseNumber,
                addressAddition: station.addressAddition,
                zip: station.zip,
                city: station.city,
                deliveryDate: station.deliveryDate,
                deliveryTime: station.deliveryTime,
                tasks:
                    station.tasks
                        .map(
                          (task) =>
                              task.id == updatedTask.id ? updatedTask : task,
                        )
                        .toList(),
              ),
            )
            .toList();

    // Create a new job instance with updated tasks
    final updatedJob = Job(
      id: job.id,
      jobNumber: job.jobNumber,
      status: job.status,
      createdAt: job.createdAt,
      updatedAt: job.updatedAt,
      createdBy: job.createdBy,
      customerSelection: job.customerSelection,
      pickupCompany: job.pickupCompany,
      pickupSalutation: job.pickupSalutation,
      pickupFirstName: job.pickupFirstName,
      pickupLastName: job.pickupLastName,
      pickupPhone: job.pickupPhone,
      pickupStreet: job.pickupStreet,
      pickupHouseNumber: job.pickupHouseNumber,
      pickupAddressAddition: job.pickupAddressAddition,
      pickupZip: job.pickupZip,
      pickupCity: job.pickupCity,
      deliveryCompany: job.deliveryCompany,
      deliverySalutation: job.deliverySalutation,
      deliveryFirstName: job.deliveryFirstName,
      deliveryLastName: job.deliveryLastName,
      deliveryPhone: job.deliveryPhone,
      deliveryStreet: job.deliveryStreet,
      deliveryHouseNumber: job.deliveryHouseNumber,
      deliveryAddressAddition: job.deliveryAddressAddition,
      deliveryZip: job.deliveryZip,
      deliveryCity: job.deliveryCity,
      digitalProcessing: job.digitalProcessing,
      appUser: job.appUser,
      pickupDate: job.pickupDate,
      pickupTime: job.pickupTime,
      deliveryDate: job.deliveryDate,
      deliveryTime: job.deliveryTime,
      remark: job.remark,
      price: job.price,
      draft: job.draft,
      cargoItems: job.cargoItems,
      deliveryStations: updatedDeliveryStations,
      tasks: updatedTasks,
      deliveryCitiesDisplay: job.deliveryCitiesDisplay,
      firstDeliveryCity: job.firstDeliveryCity,
      lastDeliveryCity: job.lastDeliveryCity,
      title: job.title,
      description: job.description,
      priority: job.priority,
      dueDate: job.dueDate,
      assignedTo: job.assignedTo,
      location: job.location,
      additionalData: job.additionalData,
    );

    // Update the job in the app state
    _appState.updateJob(updatedJob);

    setState(() {
      // Trigger UI refresh
    });

    // Close and reopen the dialog to reflect changes
    Navigator.of(context).pop();
    _showJobDetailsDialog(updatedJob);
  }

  void _showJobDetailsDialog(Job job) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text(localizeKnownText(context, job.title)),
          content: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  '${AppLocalizations.of(context).status}: ${_localizedStatusText(job.status)}',
                  style: const TextStyle(fontWeight: FontWeight.w500),
                ),
                const SizedBox(height: 8),
                Text(
                  '${AppLocalizations.of(context).priority}: ${_localizedPriorityText(job.priority)}',
                  style: const TextStyle(fontWeight: FontWeight.w500),
                ),
                const SizedBox(height: 8),
                Text(
                  '${AppLocalizations.of(context).created}: ${_formatDate(job.createdAt)}',
                  style: const TextStyle(fontWeight: FontWeight.w500),
                ),
                if (job.dueDate != null) ...[
                  const SizedBox(height: 8),
                  Text(
                    '${AppLocalizations.of(context).dueDate}: ${_formatDate(job.dueDate!)}',
                    style: const TextStyle(fontWeight: FontWeight.w500),
                  ),
                ],
                if (job.location != null) ...[
                  const SizedBox(height: 8),
                  Text(
                    '${AppLocalizations.of(context).location}: ${job.location}',
                    style: const TextStyle(fontWeight: FontWeight.w500),
                  ),
                ],
                if (job.description.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text(
                    AppLocalizations.of(context).description,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  Text(localizeKnownText(context, job.description)),
                ],
                // CargoItems section
                if (job.cargoItems.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text(
                    AppLocalizations.of(context).cargo,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  ...job.cargoItems.asMap().entries.map((entry) {
                    final cargoItem = entry.value;
                    return Container(
                      margin: const EdgeInsets.only(bottom: 8),
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: Colors.grey[50],
                        borderRadius: BorderRadius.circular(8),
                        border: Border.all(color: Colors.grey[300]!),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            cargoItem.description,
                            style: const TextStyle(fontWeight: FontWeight.w500),
                          ),
                          const SizedBox(height: 4),
                          Text(
                            '${AppLocalizations.of(context).quantity}: ${cargoItem.quantity}',
                          ),
                          Text(
                            '${AppLocalizations.of(context).weight}: ${cargoItem.formattedWeight}',
                          ),
                          Text(
                            '${AppLocalizations.of(context).dimensions}: ${cargoItem.formattedDimensions}',
                          ),
                        ],
                      ),
                    );
                  }),
                ],
                if (job.deliveryStations.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text(
                    AppLocalizations.of(
                      context,
                    ).deliveryStationsCount(job.deliveryStations.length),
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  ...job.deliveryStations.map(
                    (station) => Container(
                      margin: const EdgeInsets.only(bottom: 8),
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: Colors.grey[50],
                        borderRadius: BorderRadius.circular(8),
                        border: Border.all(color: Colors.grey[300]!),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            localizedStationLabel(
                              context,
                              station.stationOrder + 1,
                              suffix: station.displayName,
                            ),
                            style: const TextStyle(fontWeight: FontWeight.w500),
                          ),
                          if (station.formattedAddress.isNotEmpty) ...[
                            const SizedBox(height: 4),
                            Text(station.formattedAddress),
                          ],
                          if (station.tasks.isNotEmpty) ...[
                            const SizedBox(height: 4),
                            Text(
                              '${AppLocalizations.of(context).tasks}: ${station.tasks.length}',
                            ),
                          ],
                        ],
                      ),
                    ),
                  ),
                ],
                // Tasks section
                if (job.tasks.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text(
                    AppLocalizations.of(context).tasks,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  ...job.tasks.asMap().entries.map(
                    (entry) => GestureDetector(
                      onTap: () => _toggleTaskCompletion(job, entry.key),
                      child: Container(
                        margin: const EdgeInsets.only(bottom: 4),
                        padding: const EdgeInsets.symmetric(
                          vertical: 8,
                          horizontal: 4,
                        ),
                        decoration: BoxDecoration(
                          color:
                              entry.value.completed
                                  ? Colors.green.withValues(alpha: 0.1)
                                  : Colors.transparent,
                          borderRadius: BorderRadius.circular(4),
                          border: Border.all(
                            color:
                                entry.value.completed
                                    ? Colors.green.withValues(alpha: 0.3)
                                    : Colors.transparent,
                          ),
                        ),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Icon(
                              entry.value.completed
                                  ? Icons.check_circle
                                  : Icons.radio_button_unchecked,
                              size: 20,
                              color:
                                  entry.value.completed
                                      ? Colors.green
                                      : Colors.grey[600],
                            ),
                            const SizedBox(width: 8),
                            Text(
                              '${entry.key + 1}. ',
                              style: TextStyle(
                                fontWeight: FontWeight.w500,
                                decoration:
                                    entry.value.completed
                                        ? TextDecoration.lineThrough
                                        : null,
                                color:
                                    entry.value.completed
                                        ? Colors.grey[600]
                                        : null,
                              ),
                            ),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    _getTaskDisplayText(entry.value),
                                    style: TextStyle(
                                      decoration:
                                          entry.value.completed
                                              ? TextDecoration.lineThrough
                                              : null,
                                      color:
                                          entry.value.completed
                                              ? Colors.grey[600]
                                              : null,
                                    ),
                                  ),
                                  if (_getTaskStationLabel(job, entry.value) !=
                                      null) ...[
                                    const SizedBox(height: 2),
                                    Text(
                                      _getTaskStationLabel(job, entry.value)!,
                                      style: TextStyle(
                                        fontSize: 12,
                                        color: Colors.grey[600],
                                      ),
                                    ),
                                  ],
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
                if (job.additionalData != null &&
                    job.additionalData!.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text(
                    AppLocalizations.of(context).description,
                    style: const TextStyle(fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  ...job.additionalData!.entries.map(
                    (entry) => Padding(
                      padding: const EdgeInsets.only(bottom: 4),
                      child: Text('${entry.key}: ${entry.value}'),
                    ),
                  ),
                ],
              ],
            ),
          ),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: Text(AppLocalizations.of(context).close),
            ),
          ],
        );
      },
    );
  }

  String _getTaskDisplayText(Task task) {
    final l10n = AppLocalizations.of(context);
    // Generate display text based on task type
    switch (task) {
      case ConfirmationTask():
        return task.description!;

      case PhotoTask():
        return '${l10n.photoCapture} (${task.minPhotoCount}-${task.maxPhotoCount} ${l10n.photos})';

      case TodoListTask():
        return '${l10n.checklist} (${task.todoItems.length})';

      case SignatureTask():
        return l10n.signatureRequired;

      case BarcodeTask():
        return '${l10n.barcodeScan} (${task.minBarcodeCount}-${task.maxBarcodeCount})';

      case CommentTask():
        return task.required ? l10n.commentRequired : l10n.comment;

      default:
        return l10n.tasks;
    }
  }

  String? _getTaskStationLabel(Job job, Task task) {
    final stationOrder = task.stationOrder;
    if (stationOrder == null) {
      return null;
    }

    for (final station in job.deliveryStations) {
      if (station.stationOrder == stationOrder) {
        final suffix =
            station.displayName.isNotEmpty ? station.displayName : station.city;
        return localizedStationLabel(context, stationOrder + 1, suffix: suffix);
      }
    }

    return AppLocalizations.of(context).stationNumber(stationOrder + 1);
  }

  String _localizedStatusText(String status) {
    final l10n = AppLocalizations.of(context);
    switch (status.toLowerCase()) {
      case 'created':
        return l10n.statusCreated;
      case 'pending':
        return l10n.statusPending;
      case 'assigned':
        return l10n.statusAssigned;
      case 'in_progress':
      case 'started':
        return l10n.statusInProgress;
      case 'completed':
      case 'done':
        return l10n.statusCompleted;
      case 'cancelled':
        return l10n.statusCancelled;
      case 'failed':
        return l10n.statusFailed;
      default:
        return localizeKnownText(context, status);
    }
  }

  String _localizedPriorityText(String priority) {
    final l10n = AppLocalizations.of(context);
    switch (priority.toLowerCase()) {
      case 'low':
        return l10n.priorityLow;
      case 'high':
        return l10n.priorityHigh;
      case 'urgent':
        return l10n.priorityUrgent;
      case 'normal':
      default:
        return l10n.priorityMedium;
    }
  }
}
