import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_domain/krow_domain.dart';
import 'package:url_launcher/url_launcher.dart';
import '../blocs/view_orders_cubit.dart';

/// A rich card displaying details of a client order/shift.
///
/// This widget complies with the KROW Design System by using
/// tokens from `package:design_system`.
class ViewOrderCard extends StatefulWidget {
  /// Creates a [ViewOrderCard] for the given [order].
  const ViewOrderCard({required this.order, super.key});

  /// The order item to display.
  final OrderItem order;

  @override
  State<ViewOrderCard> createState() => _ViewOrderCardState();
}

class _ViewOrderCardState extends State<ViewOrderCard> {
  bool _expanded = true;

  void _openEditSheet({required OrderItem order}) {
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (BuildContext context) => _OrderEditSheet(
        order: order,
        onUpdated: () => this.context.read<ViewOrdersCubit>().updateWeekOffset(0),
      ),
    );
  }

  /// Returns the semantic color for the given status.
  Color _getStatusColor({required String status}) {
    switch (status) {
      case 'OPEN':
        return UiColors.primary;
      case 'FILLED':
      case 'CONFIRMED':
        return UiColors.textSuccess;
      case 'IN_PROGRESS':
        return UiColors.textWarning;
      case 'COMPLETED':
        return UiColors.primary;
      case 'CANCELED':
        return UiColors.destructive;
      default:
        return UiColors.textSecondary;
    }
  }

  /// Returns the localized label for the given status.
  String _getStatusLabel({required String status}) {
    switch (status) {
      case 'OPEN':
        return t.client_view_orders.card.open;
      case 'FILLED':
        return t.client_view_orders.card.filled;
      case 'CONFIRMED':
        return t.client_view_orders.card.confirmed;
      case 'IN_PROGRESS':
        return t.client_view_orders.card.in_progress;
      case 'COMPLETED':
        return t.client_view_orders.card.completed;
      case 'CANCELED':
        return t.client_view_orders.card.cancelled;
      default:
        return status.toUpperCase();
    }
  }

  /// Formats the date string for display.
  String _formatDate({required String dateStr}) {
    try {
      final DateTime date = DateTime.parse(dateStr);
      final DateTime now = DateTime.now();
      final DateTime today = DateTime(now.year, now.month, now.day);
      final DateTime tomorrow = today.add(const Duration(days: 1));
      final DateTime checkDate = DateTime(date.year, date.month, date.day);

      if (checkDate == today) return 'Today';
      if (checkDate == tomorrow) return 'Tomorrow';
      return DateFormat('EEE, MMM d').format(date);
    } catch (_) {
      return dateStr;
    }
  }

  /// Formats the time string for display.
  String _formatTime({required String timeStr}) {
    if (timeStr.isEmpty) return '';
    try {
      final List<String> parts = timeStr.split(':');
      int hour = int.parse(parts[0]);
      final int minute = int.parse(parts[1]);
      final String ampm = hour >= 12 ? 'PM' : 'AM';
      hour = hour % 12;
      if (hour == 0) hour = 12;
      return '$hour:${minute.toString().padLeft(2, '0')} $ampm';
    } catch (_) {
      return timeStr;
    }
  }

  @override
  Widget build(BuildContext context) {
    final OrderItem order = widget.order;
    final Color statusColor = _getStatusColor(status: order.status);
    final String statusLabel = _getStatusLabel(status: order.status);
    final int coveragePercent = order.workersNeeded > 0
        ? ((order.filled / order.workersNeeded) * 100).round()
        : 0;

    final double hours = order.hours;
    final double cost = order.totalValue;

    return Container(
      decoration: BoxDecoration(
        color: UiColors.white,
        borderRadius: UiConstants.radiusLg,
        border: Border.all(color: UiColors.border),
        boxShadow: <BoxShadow>[
          BoxShadow(
            color: UiColors.black.withValues(alpha: 0.04),
            blurRadius: 8,
            offset: const Offset(0, 2),
          ),
        ],
      ),
      child: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(UiConstants.space5),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                // Header Row
                Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          // Status Badge
                          Container(
                            padding: const EdgeInsets.symmetric(
                              horizontal: 8,
                              vertical: 2,
                            ),
                            decoration: BoxDecoration(
                              color: statusColor.withValues(alpha: 0.1),
                              borderRadius: BorderRadius.circular(4),
                            ),
                            child: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: <Widget>[
                                Container(
                                  width: 6,
                                  height: 6,
                                  decoration: BoxDecoration(
                                    color: statusColor,
                                    shape: BoxShape.circle,
                                  ),
                                ),
                                const SizedBox(width: 6),
                                Text(
                                  statusLabel.toUpperCase(),
                                  style: UiTypography.footnote2b.copyWith(
                                    color: statusColor,
                                    letterSpacing: 0.5,
                                  ),
                                ),
                              ],
                            ),
                          ),
                          const SizedBox(height: UiConstants.space3),
                          // Title
                          Text(
                            order.title,
                            style: UiTypography.headline4m.textPrimary,
                          ),
                          const SizedBox(height: UiConstants.space1),
                          // Client & Date
                          Row(
                            children: <Widget>[
                              Text(
                                order.clientName,
                                style: UiTypography.body3r.textSecondary,
                              ),
                              const SizedBox(width: 0),
                            ],
                          ),
                          const SizedBox(height: UiConstants.space2),
                          // Location (Hub name + Address)
                          Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              const Padding(
                                padding: EdgeInsets.only(top: 2),
                                child: Icon(
                                  UiIcons.mapPin,
                                  size: 14,
                                  color: UiColors.iconSecondary,
                                ),
                              ),
                              const SizedBox(width: 4),
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    if (order.location.isNotEmpty)
                                      Text(
                                        order.location,
                                        style: UiTypography.footnote1b.textPrimary,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                      ),
                                    if (order.locationAddress.isNotEmpty)
                                      Text(
                                        order.locationAddress,
                                        style: UiTypography.footnote2r.textSecondary,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                      ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(width: UiConstants.space3),
                    // Actions
                    Row(
                      children: <Widget>[
                        _buildHeaderIconButton(
                          icon: UiIcons.edit,
                          color: UiColors.primary,
                          bgColor: UiColors.primary.withValues(alpha: 0.08),
                          onTap: () => _openEditSheet(order: order),
                        ),
                        const SizedBox(width: UiConstants.space2),
                        if (order.confirmedApps.isNotEmpty)
                          _buildHeaderIconButton(
                            icon: _expanded
                                ? UiIcons.chevronUp
                                : UiIcons.chevronDown,
                            color: UiColors.iconSecondary,
                            bgColor: UiColors.bgSecondary,
                            onTap: () =>
                                setState(() => _expanded = !_expanded),
                          ),
                      ],
                    ),
                  ],
                ),

                const SizedBox(height: UiConstants.space4),
                const Divider(height: 1, color: UiColors.border),
                const SizedBox(height: UiConstants.space4),

                // Stats Row
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    _buildStatItem(
                      icon: UiIcons.dollar,
                      value: '\$${cost.round()}',
                      label: 'Total',
                    ),
                    _buildStatDivider(),
                    _buildStatItem(
                      icon: UiIcons.clock,
                      value: hours.toStringAsFixed(1),
                      label: 'Hrs',
                    ),
                    _buildStatDivider(),
                    _buildStatItem(
                      icon: UiIcons.users,
                      value: '${order.workersNeeded}',
                      label: 'Workers',
                    ),
                  ],
                ),

                const SizedBox(height: UiConstants.space5),

                // Times Section
                Row(
                  children: <Widget>[
                    Expanded(
                      child: _buildTimeDisplay(
                        label: 'Clock In',
                        time: _formatTime(timeStr: order.startTime),
                      ),
                    ),
                    const SizedBox(width: UiConstants.space3),
                    Expanded(
                      child: _buildTimeDisplay(
                        label: 'Clock Out',
                        time: _formatTime(timeStr: order.endTime),
                      ),
                    ),
                  ],
                ),

                const SizedBox(height: UiConstants.space4),

                // Coverage Section
                if (order.status != 'completed') ...<Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Row(
                        children: <Widget>[
                          if (order.workersNeeded != 0)
                          const Icon(
                            UiIcons.error,
                            size: 16,
                            color: UiColors.textError,
                          ),
                          const SizedBox(width: 8),
                          Text(
                            '${order.workersNeeded} Workers Needed',
                            style: UiTypography.body2m.textPrimary,
                          ),
                        ],
                      ),
                      Text(
                        '$coveragePercent%',
                        style: UiTypography.body2b.copyWith(
                          color: UiColors.primary,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 10),
                  ClipRRect(
                    borderRadius: BorderRadius.circular(100),
                    child: LinearProgressIndicator(
                      value: coveragePercent / 100,
                      backgroundColor: UiColors.bgSecondary,
                      valueColor: const AlwaysStoppedAnimation<Color>(
                        UiColors.primary,
                      ),
                      minHeight: 8,
                    ),
                  ),

                  // Avatar Stack Preview (if not expanded)
                  if (!_expanded && order.confirmedApps.isNotEmpty) ...<Widget>[
                    const SizedBox(height: UiConstants.space4),
                    Row(
                      children: <Widget>[
                        _buildAvatarStack(order.confirmedApps),
                        if (order.confirmedApps.length > 3)
                          Padding(
                            padding: const EdgeInsets.only(left: 12),
                            child: Text(
                              '+${order.confirmedApps.length - 3} more',
                              style: UiTypography.footnote2r.textSecondary,
                            ),
                          ),
                      ],
                    ),
                  ],
                ],
              ],
            ),
          ),

          // Assigned Workers (Expanded section)
          if (_expanded && order.confirmedApps.isNotEmpty) ...<Widget>[
            Container(
              decoration: const BoxDecoration(
                color: UiColors.bgSecondary,
                border: Border(top: BorderSide(color: UiColors.border)),
                borderRadius: BorderRadius.vertical(
                  bottom: Radius.circular(12),
                ),
              ),
              padding: const EdgeInsets.all(UiConstants.space5),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Text(
                        'CONFIRMED WORKERS',
                        style: UiTypography.footnote2b.textSecondary,
                      ),
                      GestureDetector(
                        onTap: () {},
                        child: Text(
                          'Message All',
                          style: UiTypography.footnote2b.copyWith(
                            color: UiColors.primary,
                          ),
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: UiConstants.space4),
                  ...order.confirmedApps
                      .take(5)
                      .map((Map<String, dynamic> app) => _buildWorkerRow(app)),
                  if (order.confirmedApps.length > 5)
                    Padding(
                      padding: const EdgeInsets.only(top: 8),
                      child: Center(
                        child: TextButton(
                          onPressed: () {},
                          child: Text(
                            'Show ${order.confirmedApps.length - 5} more workers',
                            style: UiTypography.body2m.copyWith(
                              color: UiColors.primary,
                            ),
                          ),
                        ),
                      ),
                    ),
                ],
              ),
            ),
          ],
        ],
      ),
    );
  }

  Widget _buildStatDivider() {
    return Container(width: 1, height: 24, color: UiColors.border);
  }

  Widget _buildTimeDisplay({required String label, required String time}) {
    return Container(
      padding: const EdgeInsets.all(UiConstants.space3),
      decoration: BoxDecoration(
        color: UiColors.bgSecondary,
        borderRadius: UiConstants.radiusMd,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            label.toUpperCase(),
            style: UiTypography.titleUppercase4m.textSecondary,
          ),
          const SizedBox(height: 4),
          Text(time, style: UiTypography.body1b.textPrimary),
        ],
      ),
    );
  }

  /// Builds a stacked avatar UI for a list of applications.
  Widget _buildAvatarStack(List<Map<String, dynamic>> apps) {
    const double size = 32.0;
    const double overlap = 22.0;
    final int count = apps.length > 3 ? 3 : apps.length;

    return SizedBox(
      height: size,
      width: size + (count - 1) * overlap,
      child: Stack(
        children: <Widget>[
          for (int i = 0; i < count; i++)
            Positioned(
              left: i * overlap,
              child: Container(
                width: size,
                height: size,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(color: UiColors.white, width: 2),
                  color: UiColors.primary.withValues(alpha: 0.1),
                ),
                child: Center(
                  child: Text(
                    (apps[i]['worker_name'] as String)[0],
                    style: UiTypography.footnote2b.copyWith(
                      color: UiColors.primary,
                    ),
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }

  /// Builds a detailed row for a worker.
  Widget _buildWorkerRow(Map<String, dynamic> app) {
    final String? phone = app['phone'] as String?;
    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: UiColors.white,
        borderRadius: UiConstants.radiusMd,
        border: Border.all(color: UiColors.border),
      ),
      child: Row(
        children: <Widget>[
          CircleAvatar(
            radius: 20,
            backgroundColor: UiColors.primary.withValues(alpha: 0.1),
            child: Text(
              (app['worker_name'] as String)[0],
              style: UiTypography.body1b.copyWith(color: UiColors.primary),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  app['worker_name'] as String,
                  style: UiTypography.body2m.textPrimary,
                ),
                const SizedBox(height: 2),
                Row(
                  children: <Widget>[
                    if ((app['rating'] as num?) != null &&
                        (app['rating'] as num) > 0) ...<Widget>[
                      const Icon(
                        UiIcons.star,
                        size: 10,
                        color: UiColors.accent,
                      ),
                      const SizedBox(width: 2),
                      Text(
                        (app['rating'] as num).toStringAsFixed(1),
                        style: UiTypography.footnote2r.textSecondary,
                      ),
                    ],
                    if (app['check_in_time'] != null) ...<Widget>[
                      const SizedBox(width: 8),
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 4,
                          vertical: 1,
                        ),
                        decoration: BoxDecoration(
                          color: UiColors.textSuccess.withValues(alpha: 0.1),
                          borderRadius: BorderRadius.circular(4),
                        ),
                        child: Text(
                          'Checked In',
                          style: UiTypography.titleUppercase4m.copyWith(
                            color: UiColors.textSuccess,
                          ),
                        ),
                      ),
                    ] else if ((app['status'] as String?)?.isNotEmpty ?? false) ...<Widget>[
                      const SizedBox(width: 8),
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 4,
                          vertical: 1,
                        ),
                        decoration: BoxDecoration(
                          color: UiColors.bgSecondary,
                          borderRadius: BorderRadius.circular(4),
                        ),
                        child: Text(
                          (app['status'] as String).toUpperCase(),
                          style: UiTypography.titleUppercase4m.copyWith(
                            color: UiColors.textSecondary,
                          ),
                        ),
                      ),
                    ],
                  ],
                ),
              ],
            ),
          ),
          if (phone != null && phone.isNotEmpty) ...<Widget>[
            _buildActionIconButton(
              icon: UiIcons.phone,
              onTap: () => _confirmAndCall(phone),
            ),
          ],
        ],
      ),
    );
  }

  Future<void> _confirmAndCall(String phone) async {
    final bool? shouldCall = await showDialog<bool>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Call'),
          content: Text('Do you want to call $phone?'),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.of(context).pop(false),
              child: const Text('Cancel'),
            ),
            TextButton(
              onPressed: () => Navigator.of(context).pop(true),
              child: const Text('Call'),
            ),
          ],
        );
      },
    );

    if (shouldCall != true) {
      return;
    }

    final Uri uri = Uri(scheme: 'tel', path: phone);
    await launchUrl(uri);
  }

  /// Specialized action button for worker rows.
  Widget _buildActionIconButton({
    required IconData icon,
    required VoidCallback onTap,
  }) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 36,
        height: 36,
        decoration: BoxDecoration(
          color: UiColors.bgSecondary,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Icon(icon, size: 16, color: UiColors.primary),
      ),
    );
  }

  /// Builds a small icon button used in row headers.
  Widget _buildHeaderIconButton({
    required IconData icon,
    required Color color,
    required Color bgColor,
    required VoidCallback onTap,
  }) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.all(10),
        decoration: BoxDecoration(
          color: bgColor,
          borderRadius: UiConstants.radiusSm,
        ),
        child: Icon(icon, size: 16, color: color),
      ),
    );
  }

  /// Builds a single stat item (e.g., Cost, Hours, Workers).
  Widget _buildStatItem({
    required IconData icon,
    required String value,
    required String label,
  }) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(icon, size: 14, color: UiColors.iconSecondary),
            const SizedBox(width: 6),
            Text(value, style: UiTypography.body1b.textPrimary),
          ],
        ),
        const SizedBox(height: 2),
        Text(
          label.toUpperCase(),
          style: UiTypography.titleUppercase4m.textInactive,
        ),
      ],
    );
  }
}

class _RoleOption {
  const _RoleOption({
    required this.id,
    required this.name,
    required this.costPerHour,
  });

  final String id;
  final String name;
  final double costPerHour;
}

class _ShiftRoleKey {
  const _ShiftRoleKey({required this.shiftId, required this.roleId});

  final String shiftId;
  final String roleId;
}

/// A sophisticated bottom sheet for editing an existing order,
/// following the Unified Order Flow prototype and matching OneTimeOrderView.
class _OrderEditSheet extends StatefulWidget {
  const _OrderEditSheet({
    required this.order,
    this.onUpdated,
  });

  final OrderItem order;
  final VoidCallback? onUpdated;

  @override
  State<_OrderEditSheet> createState() => _OrderEditSheetState();
}

class _OrderEditSheetState extends State<_OrderEditSheet> {
  bool _showReview = false;
  bool _isLoading = false;

  late TextEditingController _dateController;
  late TextEditingController _globalLocationController;
  late TextEditingController _orderNameController;

  late List<Map<String, dynamic>> _positions;

  final dc.ExampleConnector _dataConnect = dc.ExampleConnector.instance;
  final firebase.FirebaseAuth _firebaseAuth = firebase.FirebaseAuth.instance;

  List<Vendor> _vendors = const <Vendor>[];
  Vendor? _selectedVendor;
  List<_RoleOption> _roles = const <_RoleOption>[];
  List<dc.ListTeamHubsByOwnerIdTeamHubs> _hubs = const <dc.ListTeamHubsByOwnerIdTeamHubs>[];
  dc.ListTeamHubsByOwnerIdTeamHubs? _selectedHub;

  String? _shiftId;
  List<_ShiftRoleKey> _originalShiftRoles = const <_ShiftRoleKey>[];

  @override
  void initState() {
    super.initState();
    _dateController = TextEditingController(text: widget.order.date);
    _globalLocationController = TextEditingController(
      text: widget.order.locationAddress,
    );
    _orderNameController = TextEditingController();

    _positions = <Map<String, dynamic>>[
      <String, dynamic>{
        'shiftId': null,
        'roleId': '',
        'roleName': '',
        'originalRoleId': null,
        'count': widget.order.workersNeeded,
        'start_time': widget.order.startTime,
        'end_time': widget.order.endTime,
        'lunch_break': 'NO_BREAK',
        'location': null,
      },
    ];

    _loadOrderDetails();
  }

  @override
  void dispose() {
    _dateController.dispose();
    _globalLocationController.dispose();
    _orderNameController.dispose();
    super.dispose();
  }

  Future<void> _loadOrderDetails() async {
    final String? businessId =
        dc.ClientSessionStore.instance.session?.business?.id;
    if (businessId == null || businessId.isEmpty) {
      await _firebaseAuth.signOut();
      return;
    }

    if (widget.order.orderId.isEmpty) {
      return;
    }

    try {
      final QueryResult<
          dc.ListShiftRolesByBusinessAndOrderData,
          dc.ListShiftRolesByBusinessAndOrderVariables> result = await _dataConnect
          .listShiftRolesByBusinessAndOrder(
            businessId: businessId,
            orderId: widget.order.orderId,
          )
          .execute();

      final List<dc.ListShiftRolesByBusinessAndOrderShiftRoles> shiftRoles =
          result.data.shiftRoles;
      if (shiftRoles.isEmpty) {
        await _loadHubsAndSelect();
        return;
      }

      final dc.ListShiftRolesByBusinessAndOrderShiftRolesShift firstShift =
          shiftRoles.first.shift;
      final DateTime? orderDate = firstShift.order.date?.toDateTime();
      final String dateText = orderDate == null
          ? widget.order.date
          : DateFormat('yyyy-MM-dd').format(orderDate);
      final String location = firstShift.order.teamHub?.hubName ??
          firstShift.locationAddress ??
          firstShift.location ??
          widget.order.locationAddress;

      _dateController.text = dateText;
      _globalLocationController.text = location;
      _orderNameController.text = firstShift.order.eventName ?? '';
      _shiftId = shiftRoles.first.shiftId;

      final List<Map<String, dynamic>> positions =
          shiftRoles.map((dc.ListShiftRolesByBusinessAndOrderShiftRoles role) {
        return <String, dynamic>{
          'shiftId': role.shiftId,
          'roleId': role.roleId,
          'roleName': role.role.name,
          'originalRoleId': role.roleId,
          'count': role.count,
          'start_time': _formatTimeForField(role.startTime),
          'end_time': _formatTimeForField(role.endTime),
          'lunch_break': _breakValueFromDuration(role.breakType),
          'location': null,
        };
      }).toList();

      if (positions.isEmpty) {
        positions.add(_emptyPosition());
      }

      final List<_ShiftRoleKey> originalShiftRoles =
          shiftRoles
              .map(
                (dc.ListShiftRolesByBusinessAndOrderShiftRoles role) =>
                    _ShiftRoleKey(shiftId: role.shiftId, roleId: role.roleId),
              )
              .toList();

      await _loadVendorsAndSelect(firstShift.order.vendorId);
      final dc.ListShiftRolesByBusinessAndOrderShiftRolesShiftOrderTeamHub?
      teamHub = firstShift.order.teamHub;
      await _loadHubsAndSelect(
        placeId: teamHub?.placeId,
        hubName: teamHub?.hubName,
        address: teamHub?.address,
      );

      if (mounted) {
        setState(() {
          _positions = positions;
          _originalShiftRoles = originalShiftRoles;
        });
      }
    } catch (_) {
      // Keep current state on failure.
    }
  }

  Future<void> _loadHubsAndSelect({
    String? placeId,
    String? hubName,
    String? address,
  }) async {
    final String? businessId =
        dc.ClientSessionStore.instance.session?.business?.id;
    if (businessId == null || businessId.isEmpty) {
      return;
    }

    try {
      final QueryResult<
          dc.ListTeamHubsByOwnerIdData,
          dc.ListTeamHubsByOwnerIdVariables> result = await _dataConnect
          .listTeamHubsByOwnerId(ownerId: businessId)
          .execute();

      final List<dc.ListTeamHubsByOwnerIdTeamHubs> hubs = result.data.teamHubs;
      dc.ListTeamHubsByOwnerIdTeamHubs? selected;

      if (placeId != null && placeId.isNotEmpty) {
        for (final dc.ListTeamHubsByOwnerIdTeamHubs hub in hubs) {
          if (hub.placeId == placeId) {
            selected = hub;
            break;
          }
        }
      }

      if (selected == null && hubName != null && hubName.isNotEmpty) {
        for (final dc.ListTeamHubsByOwnerIdTeamHubs hub in hubs) {
          if (hub.hubName == hubName) {
            selected = hub;
            break;
          }
        }
      }

      if (selected == null && address != null && address.isNotEmpty) {
        for (final dc.ListTeamHubsByOwnerIdTeamHubs hub in hubs) {
          if (hub.address == address) {
            selected = hub;
            break;
          }
        }
      }

      selected ??= hubs.isNotEmpty ? hubs.first : null;

      if (mounted) {
        setState(() {
          _hubs = hubs;
          _selectedHub = selected;
          if (selected != null) {
            _globalLocationController.text = selected.address;
          }
        });
      }
    } catch (_) {
      if (mounted) {
        setState(() {
          _hubs = const <dc.ListTeamHubsByOwnerIdTeamHubs>[];
          _selectedHub = null;
        });
      }
    }
  }

  Future<void> _loadVendorsAndSelect(String? selectedVendorId) async {
    try {
      final QueryResult<dc.ListVendorsData, void> result =
          await _dataConnect.listVendors().execute();
      final List<Vendor> vendors = result.data.vendors
          .map(
            (dc.ListVendorsVendors vendor) => Vendor(
              id: vendor.id,
              name: vendor.companyName,
              rates: const <String, double>{},
            ),
          )
          .toList();

      Vendor? selectedVendor;
      if (selectedVendorId != null && selectedVendorId.isNotEmpty) {
        for (final Vendor vendor in vendors) {
          if (vendor.id == selectedVendorId) {
            selectedVendor = vendor;
            break;
          }
        }
      }
      selectedVendor ??= vendors.isNotEmpty ? vendors.first : null;

      if (mounted) {
        setState(() {
          _vendors = vendors;
          _selectedVendor = selectedVendor;
        });
      }

      if (selectedVendor != null) {
        await _loadRolesForVendor(selectedVendor.id);
      }
    } catch (_) {
      if (mounted) {
        setState(() {
          _vendors = const <Vendor>[];
          _selectedVendor = null;
          _roles = const <_RoleOption>[];
        });
      }
    }
  }

  Future<void> _loadRolesForVendor(String vendorId) async {
    try {
      final QueryResult<dc.ListRolesByVendorIdData, dc.ListRolesByVendorIdVariables>
          result = await _dataConnect
              .listRolesByVendorId(vendorId: vendorId)
              .execute();
      final List<_RoleOption> roles = result.data.roles
          .map(
            (dc.ListRolesByVendorIdRoles role) => _RoleOption(
              id: role.id,
              name: role.name,
              costPerHour: role.costPerHour,
            ),
          )
          .toList();
      if (mounted) {
        setState(() => _roles = roles);
      }
    } catch (_) {
      if (mounted) {
        setState(() => _roles = const <_RoleOption>[]);
      }
    }
  }

  Map<String, dynamic> _emptyPosition() {
    return <String, dynamic>{
      'shiftId': _shiftId,
      'roleId': '',
      'roleName': '',
      'originalRoleId': null,
      'count': 1,
      'start_time': '09:00',
      'end_time': '17:00',
      'lunch_break': 'NO_BREAK',
      'location': null,
    };
  }

  String _formatTimeForField(Timestamp? value) {
    if (value == null) return '';
    try {
      return DateFormat('HH:mm').format(value.toDateTime().toLocal());
    } catch (_) {
      return '';
    }
  }

  String _breakValueFromDuration(dc.EnumValue<dc.BreakDuration>? breakType) {
    final dc.BreakDuration? value =
        breakType is dc.Known<dc.BreakDuration> ? breakType.value : null;
    switch (value) {
      case dc.BreakDuration.MIN_15:
        return 'MIN_15';
      case dc.BreakDuration.MIN_30:
        return 'MIN_30';
      case dc.BreakDuration.NO_BREAK:
      case null:
        return 'NO_BREAK';
    }
  }

  dc.BreakDuration _breakDurationFromValue(String value) {
    switch (value) {
      case 'MIN_15':
        return dc.BreakDuration.MIN_15;
      case 'MIN_30':
        return dc.BreakDuration.MIN_30;
      default:
        return dc.BreakDuration.NO_BREAK;
    }
  }

  _RoleOption? _roleById(String roleId) {
    for (final _RoleOption role in _roles) {
      if (role.id == roleId) {
        return role;
      }
    }
    return null;
  }

  double _rateForRole(String roleId) {
    return _roleById(roleId)?.costPerHour ?? 0;
  }

  DateTime _parseDate(String value) {
    try {
      return DateFormat('yyyy-MM-dd').parse(value);
    } catch (_) {
      return DateTime.now();
    }
  }

  DateTime _parseTime(DateTime date, String time) {
    if (time.trim().isEmpty) {
      throw Exception('Shift time is missing.');
    }

    DateTime parsed;
    try {
      parsed = DateFormat.Hm().parse(time);
    } catch (_) {
      parsed = DateFormat.jm().parse(time);
    }

    return DateTime(
      date.year,
      date.month,
      date.day,
      parsed.hour,
      parsed.minute,
    );
  }

  Timestamp _toTimestamp(DateTime date) {
    final DateTime utc = date.toUtc();
    final int millis = utc.millisecondsSinceEpoch;
    final int seconds = millis ~/ 1000;
    final int nanos = (millis % 1000) * 1000000;
    return Timestamp(nanos, seconds);
  }

  double _calculateTotalCost() {
    double total = 0;
    for (final Map<String, dynamic> pos in _positions) {
      final String roleId = pos['roleId']?.toString() ?? '';
      if (roleId.isEmpty) {
        continue;
      }
      final DateTime date = _parseDate(_dateController.text);
      final DateTime start = _parseTime(date, pos['start_time'].toString());
      final DateTime end = _parseTime(date, pos['end_time'].toString());
      final DateTime normalizedEnd =
          end.isBefore(start) ? end.add(const Duration(days: 1)) : end;
      final double hours = normalizedEnd.difference(start).inMinutes / 60.0;
      final double rate = _rateForRole(roleId);
      final int count = pos['count'] as int;
      total += rate * hours * count;
    }
    return total;
  }

  Future<void> _saveOrderChanges() async {
    if (_shiftId == null || _shiftId!.isEmpty) {
      return;
    }

    final String? businessId =
        dc.ClientSessionStore.instance.session?.business?.id;
    if (businessId == null || businessId.isEmpty) {
      await _firebaseAuth.signOut();
      return;
    }

    final DateTime orderDate = _parseDate(_dateController.text);
    final dc.ListTeamHubsByOwnerIdTeamHubs? selectedHub = _selectedHub;
    if (selectedHub == null) {
      return;
    }

    int totalWorkers = 0;
    double shiftCost = 0;

    final List<_ShiftRoleKey> remainingOriginal =
        List<_ShiftRoleKey>.from(_originalShiftRoles);

    for (final Map<String, dynamic> pos in _positions) {
      final String roleId = pos['roleId']?.toString() ?? '';
      if (roleId.isEmpty) {
        continue;
      }

      final String shiftId = pos['shiftId']?.toString() ?? _shiftId!;
      final int count = pos['count'] as int;
      final DateTime start = _parseTime(orderDate, pos['start_time'].toString());
      final DateTime end = _parseTime(orderDate, pos['end_time'].toString());
      final DateTime normalizedEnd =
          end.isBefore(start) ? end.add(const Duration(days: 1)) : end;
      final double hours = normalizedEnd.difference(start).inMinutes / 60.0;
      final double rate = _rateForRole(roleId);
      final double totalValue = rate * hours * count;
      final String lunchBreak = pos['lunch_break'] as String;

      totalWorkers += count;
      shiftCost += totalValue;

      final String? originalRoleId = pos['originalRoleId']?.toString();
      remainingOriginal.removeWhere(
        (_ShiftRoleKey key) =>
            key.shiftId == shiftId && key.roleId == originalRoleId,
      );

      if (originalRoleId != null && originalRoleId.isNotEmpty) {
        if (originalRoleId != roleId) {
          await _dataConnect
              .deleteShiftRole(shiftId: shiftId, roleId: originalRoleId)
              .execute();
          await _dataConnect
              .createShiftRole(
                shiftId: shiftId,
                roleId: roleId,
                count: count,
              )
              .startTime(_toTimestamp(start))
              .endTime(_toTimestamp(normalizedEnd))
              .hours(hours)
              .breakType(_breakDurationFromValue(lunchBreak))
              .totalValue(totalValue)
              .execute();
        } else {
          await _dataConnect
              .updateShiftRole(shiftId: shiftId, roleId: roleId)
              .count(count)
              .startTime(_toTimestamp(start))
              .endTime(_toTimestamp(normalizedEnd))
              .hours(hours)
              .breakType(_breakDurationFromValue(lunchBreak))
              .totalValue(totalValue)
              .execute();
        }
      } else {
        await _dataConnect
            .createShiftRole(
              shiftId: shiftId,
              roleId: roleId,
              count: count,
            )
            .startTime(_toTimestamp(start))
            .endTime(_toTimestamp(normalizedEnd))
            .hours(hours)
            .breakType(_breakDurationFromValue(lunchBreak))
            .totalValue(totalValue)
            .execute();
      }
    }

    for (final _ShiftRoleKey key in remainingOriginal) {
      await _dataConnect
          .deleteShiftRole(shiftId: key.shiftId, roleId: key.roleId)
          .execute();
    }

    final DateTime orderDateOnly = DateTime.utc(
      orderDate.year,
      orderDate.month,
      orderDate.day,
    );

    await _dataConnect
        .updateOrder(id: widget.order.orderId, teamHubId: selectedHub.id)
        .vendorId(_selectedVendor?.id)
        .date(_toTimestamp(orderDateOnly))
        .eventName(_orderNameController.text)
        .execute();

    await _dataConnect
        .updateShift(id: _shiftId!)
        .title('shift 1 ${DateFormat('yyyy-MM-dd').format(orderDate)}')
        .date(_toTimestamp(orderDateOnly))
        .location(selectedHub.hubName)
        .locationAddress(selectedHub.address)
        .latitude(selectedHub.latitude)
        .longitude(selectedHub.longitude)
        .placeId(selectedHub.placeId)
        .city(selectedHub.city)
        .state(selectedHub.state)
        .street(selectedHub.street)
        .country(selectedHub.country)
        .workersNeeded(totalWorkers)
        .cost(shiftCost)
        .durationDays(1)
        .execute();
  }

  void _addPosition() {
    setState(() {
      _positions.add(_emptyPosition());
    });
  }

  void _removePosition(int index) {
    if (_positions.length > 1) {
      setState(() => _positions.removeAt(index));
    }
  }

  void _updatePosition(int index, String key, dynamic value) {
    setState(() => _positions[index][key] = value);
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading && _showReview) {
      return _buildSuccessView();
    }

    return _showReview ? _buildReviewView() : _buildFormView();
  }

  Widget _buildFormView() {
    return Container(
      height: MediaQuery.of(context).size.height * 0.95,
      decoration: const BoxDecoration(
        color: UiColors.bgPrimary,
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Column(
        children: <Widget>[
          _buildHeader(),
          Expanded(
            child: ListView(
              padding: const EdgeInsets.all(UiConstants.space5),
              children: <Widget>[
                Text(
                  'Edit Your Order',
                  style: UiTypography.headline3m.textPrimary,
                ),
                const SizedBox(height: UiConstants.space4),

                _buildSectionHeader('VENDOR'),
                Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: UiConstants.space3,
                  ),
                  height: 48,
                  decoration: BoxDecoration(
                    color: UiColors.white,
                    borderRadius: UiConstants.radiusMd,
                    border: Border.all(color: UiColors.border),
                  ),
                  child: DropdownButtonHideUnderline(
                    child: DropdownButton<Vendor>(
                      isExpanded: true,
                      value: _selectedVendor,
                      icon: const Icon(
                        UiIcons.chevronDown,
                        size: 18,
                        color: UiColors.iconSecondary,
                      ),
                      onChanged: (Vendor? vendor) {
                        if (vendor != null) {
                          setState(() => _selectedVendor = vendor);
                          _loadRolesForVendor(vendor.id);
                        }
                      },
                      items: _vendors.map((Vendor vendor) {
                        return DropdownMenuItem<Vendor>(
                          value: vendor,
                          child: Text(
                            vendor.name,
                            style: UiTypography.body2m.textPrimary,
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                ),
                const SizedBox(height: UiConstants.space4),

                _buildSectionHeader('DATE'),
                UiTextField(
                  controller: _dateController,
                  hintText: 'mm/dd/yyyy',
                  prefixIcon: UiIcons.calendar,
                  readOnly: true,
                  onTap: () {},
                ),
                const SizedBox(height: UiConstants.space4),

                _buildSectionHeader('ORDER NAME'),
                UiTextField(
                  controller: _orderNameController,
                  hintText: 'Order name',
                  prefixIcon: UiIcons.briefcase,
                ),
                const SizedBox(height: UiConstants.space4),

                _buildSectionHeader('HUB'),
                Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: UiConstants.space3,
                  ),
                  height: 48,
                  decoration: BoxDecoration(
                    color: UiColors.white,
                    borderRadius: UiConstants.radiusMd,
                    border: Border.all(color: UiColors.border),
                  ),
                  child: DropdownButtonHideUnderline(
                    child: DropdownButton<dc.ListTeamHubsByOwnerIdTeamHubs>(
                      isExpanded: true,
                      value: _selectedHub,
                      icon: const Icon(
                        UiIcons.chevronDown,
                        size: 18,
                        color: UiColors.iconSecondary,
                      ),
                      onChanged:
                          (dc.ListTeamHubsByOwnerIdTeamHubs? hub) {
                        if (hub != null) {
                          setState(() {
                            _selectedHub = hub;
                            _globalLocationController.text = hub.address;
                          });
                        }
                      },
                      items: _hubs.map(
                        (dc.ListTeamHubsByOwnerIdTeamHubs hub) {
                          return DropdownMenuItem<
                              dc.ListTeamHubsByOwnerIdTeamHubs>(
                            value: hub,
                            child: Text(
                              hub.hubName,
                              style: UiTypography.body2m.textPrimary,
                            ),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ),
                const SizedBox(height: UiConstants.space6),

                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Text(
                      'POSITIONS',
                      style: UiTypography.headline4m.textPrimary,
                    ),
                    TextButton(
                      onPressed: _addPosition,
                      style: TextButton.styleFrom(
                        padding: EdgeInsets.zero,
                        minimumSize: Size.zero,
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      ),
                      child: const Row(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Icon(UiIcons.add, size: 16, color: UiColors.primary),
                          SizedBox(width: UiConstants.space2),
                          Text(
                            'Add Position',
                            style: TextStyle(
                              color: UiColors.primary,
                              fontSize: 14,
                              fontWeight: FontWeight.w500,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: UiConstants.space3),

                ..._positions.asMap().entries.map((
                  MapEntry<int, Map<String, dynamic>> entry,
                ) {
                  return _buildPositionCard(entry.key, entry.value);
                }),

                const SizedBox(height: 40),
              ],
            ),
          ),
          _buildBottomAction(
            label: 'Review ${_positions.length} Positions',
            onPressed: () => setState(() => _showReview = true),
          ),
        ],
      ),
    );
  }

  Widget _buildHeader() {
    return Container(
      padding: const EdgeInsets.fromLTRB(20, 24, 20, 20),
      decoration: const BoxDecoration(
        color: UiColors.primary,
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Row(
        children: <Widget>[
          GestureDetector(
            onTap: () => Navigator.pop(context),
            child: Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                color: UiColors.white.withValues(alpha: 0.2),
                borderRadius: UiConstants.radiusMd,
              ),
              child: const Icon(
                UiIcons.chevronLeft,
                color: UiColors.white,
                size: 24,
              ),
            ),
          ),
          const SizedBox(width: UiConstants.space3),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                'One-Time Order',
                style: UiTypography.headline3m.copyWith(color: UiColors.white),
              ),
              Text(
                'Refine your staffing needs',
                style: UiTypography.footnote2r.copyWith(
                  color: UiColors.white.withValues(alpha: 0.8),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildSectionHeader(String title) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: Text(title, style: UiTypography.footnote2r.textSecondary),
    );
  }

  Widget _buildPositionCard(int index, Map<String, dynamic> pos) {
    return Container(
      margin: const EdgeInsets.only(bottom: UiConstants.space3),
      padding: const EdgeInsets.all(UiConstants.space4),
      decoration: BoxDecoration(
        color: UiColors.white,
        borderRadius: UiConstants.radiusLg,
        border: Border.all(color: UiColors.border),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                'POSITION #${index + 1}',
                style: UiTypography.footnote1m.textSecondary,
              ),
              if (_positions.length > 1)
                GestureDetector(
                  onTap: () => _removePosition(index),
                  child: Text(
                    'Remove',
                    style: UiTypography.footnote1m.copyWith(
                      color: UiColors.destructive,
                    ),
                  ),
                ),
            ],
          ),
          const SizedBox(height: UiConstants.space3),

          _buildDropdownField(
            hint: 'Select role',
            value: pos['roleId'],
            items: <String>[
              ..._roles.map((_RoleOption role) => role.id),
              if (pos['roleId'] != null &&
                  pos['roleId'].toString().isNotEmpty &&
                  !_roles.any(
                    (_RoleOption role) => role.id == pos['roleId'].toString(),
                  ))
                pos['roleId'].toString(),
            ],
            itemBuilder: (dynamic roleId) {
              final _RoleOption? role = _roleById(roleId.toString());
              if (role == null) {
                final String fallback = pos['roleName']?.toString() ?? '';
                return fallback.isEmpty ? roleId.toString() : fallback;
              }
              return '${role.name} - \$${role.costPerHour.toStringAsFixed(0)}/hr';
            },
            onChanged: (dynamic val) {
              final String roleId = val?.toString() ?? '';
              final _RoleOption? role = _roleById(roleId);
              setState(() {
                _positions[index]['roleId'] = roleId;
                _positions[index]['roleName'] = role?.name ?? '';
              });
            },
          ),

          const SizedBox(height: UiConstants.space3),

          Row(
            children: <Widget>[
              Expanded(
                child: _buildInlineTimeInput(
                  label: 'Start',
                  value: pos['start_time'],
                  onTap: () async {
                    final TimeOfDay? picked = await showTimePicker(
                      context: context,
                      initialTime: TimeOfDay.now(),
                    );
                    if (picked != null && context.mounted) {
                      _updatePosition(
                        index,
                        'start_time',
                        picked.format(context),
                      );
                    }
                  },
                ),
              ),
              const SizedBox(width: UiConstants.space2),
              Expanded(
                child: _buildInlineTimeInput(
                  label: 'End',
                  value: pos['end_time'],
                  onTap: () async {
                    final TimeOfDay? picked = await showTimePicker(
                      context: context,
                      initialTime: TimeOfDay.now(),
                    );
                    if (picked != null && context.mounted) {
                      _updatePosition(
                        index,
                        'end_time',
                        picked.format(context),
                      );
                    }
                  },
                ),
              ),
              const SizedBox(width: UiConstants.space2),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      'Workers',
                      style: UiTypography.footnote2r.textSecondary,
                    ),
                    const SizedBox(height: UiConstants.space1),
                    Container(
                      height: 40,
                      decoration: BoxDecoration(
                        color: UiColors.bgSecondary,
                        borderRadius: UiConstants.radiusSm,
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          GestureDetector(
                            onTap: () {
                              if ((pos['count'] as int) > 1) {
                                _updatePosition(
                                  index,
                                  'count',
                                  (pos['count'] as int) - 1,
                                );
                              }
                            },
                            child: const Icon(UiIcons.minus, size: 12),
                          ),
                          Text(
                            '${pos['count']}',
                            style: UiTypography.body2b.textPrimary,
                          ),
                          GestureDetector(
                            onTap: () => _updatePosition(
                              index,
                              'count',
                              (pos['count'] as int) + 1,
                            ),
                            child: const Icon(UiIcons.add, size: 12),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: UiConstants.space4),

          if (pos['location'] == null)
            GestureDetector(
              onTap: () => _updatePosition(index, 'location', ''),
              child: Row(
                children: <Widget>[
                  const Icon(UiIcons.mapPin, size: 14, color: UiColors.primary),
                  const SizedBox(width: UiConstants.space1),
                  Text(
                    'Use different location for this position',
                    style: UiTypography.footnote1m.copyWith(
                      color: UiColors.primary,
                    ),
                  ),
                ],
              ),
            )
          else
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        const Icon(
                          UiIcons.mapPin,
                          size: 14,
                          color: UiColors.iconSecondary,
                        ),
                        const SizedBox(width: UiConstants.space1),
                        Text(
                          'Different Location',
                          style: UiTypography.footnote1m.textSecondary,
                        ),
                      ],
                    ),
                    GestureDetector(
                      onTap: () => _updatePosition(index, 'location', null),
                      child: const Icon(
                        UiIcons.close,
                        size: 14,
                        color: UiColors.destructive,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: UiConstants.space2),
                UiTextField(
                  controller: TextEditingController(text: pos['location']),
                  hintText: 'Enter different address',
                  onChanged: (String val) =>
                      _updatePosition(index, 'location', val),
                ),
              ],
            ),

          const SizedBox(height: UiConstants.space3),

          _buildSectionHeader('LUNCH BREAK'),
          _buildDropdownField(
            hint: 'No break',
            value: pos['lunch_break'],
            items: <String>['NO_BREAK', 'MIN_15', 'MIN_30'],
            itemBuilder: (dynamic val) {
              switch (val.toString()) {
                case 'MIN_15':
                  return '15 min';
                case 'MIN_30':
                  return '30 min';
                default:
                  return 'No break';
              }
            },
            onChanged: (dynamic val) =>
                _updatePosition(index, 'lunch_break', val),
          ),
        ],
      ),
    );
  }

  Widget _buildDropdownField({
    required String hint,
    required dynamic value,
    required List<dynamic> items,
    String Function(dynamic)? itemBuilder,
    required ValueChanged<dynamic> onChanged,
  }) {
    return Container(
      height: 44,
      padding: const EdgeInsets.symmetric(horizontal: UiConstants.space3),
      decoration: BoxDecoration(
        borderRadius: UiConstants.radiusMd,
        border: Border.all(color: UiColors.border),
      ),
      child: DropdownButtonHideUnderline(
        child: DropdownButton<dynamic>(
          isExpanded: true,
          hint: Text(hint, style: UiTypography.body2r.textPlaceholder),
          value: value == '' || value == null ? null : value,
          icon: const Icon(
            UiIcons.chevronDown,
            size: 18,
            color: UiColors.iconSecondary,
          ),
          onChanged: onChanged,
          items: items.toSet().map((dynamic item) {
            String label = item.toString();
            if (itemBuilder != null) label = itemBuilder(item);
            return DropdownMenuItem<dynamic>(
              value: item,
              child: Text(label, style: UiTypography.body2r.textPrimary),
            );
          }).toList(),
        ),
      ),
    );
  }

  Widget _buildInlineTimeInput({
    required String label,
    required String value,
    required VoidCallback onTap,
  }) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Text(label, style: UiTypography.footnote2r.textSecondary),
        const SizedBox(height: UiConstants.space1),
        GestureDetector(
          onTap: onTap,
          child: Container(
            height: 40,
            padding: const EdgeInsets.symmetric(horizontal: UiConstants.space3),
            decoration: BoxDecoration(
              borderRadius: UiConstants.radiusSm,
              border: Border.all(color: UiColors.border),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text(
                  value.isEmpty ? '--:--' : value,
                  style: UiTypography.body2r.textPrimary,
                ),
                const Icon(
                  UiIcons.clock,
                  size: 14,
                  color: UiColors.iconSecondary,
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildBottomAction({
    required String label,
    required VoidCallback onPressed,
  }) {
    return Container(
      padding: EdgeInsets.fromLTRB(
        UiConstants.space5,
        UiConstants.space5,
        UiConstants.space5,
        MediaQuery.of(context).padding.bottom + UiConstants.space5,
      ),
      decoration: const BoxDecoration(
        color: UiColors.white,
        border: Border(top: BorderSide(color: UiColors.border)),
      ),
      child: SizedBox(
        width: double.infinity,
        child: UiButton.primary(
          text: label,
          onPressed: onPressed,
          size: UiButtonSize.large,
        ),
      ),
    );
  }

  Widget _buildReviewView() {
    final int totalWorkers = _positions.fold<int>(
      0,
      (int sum, Map<String, dynamic> p) => sum + (p['count'] as int),
    );
    final double totalCost = _calculateTotalCost();

    return Container(
      height: MediaQuery.of(context).size.height * 0.95,
      decoration: const BoxDecoration(
        color: UiColors.bgSecondary,
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Column(
        children: <Widget>[
          _buildHeader(),
          Expanded(
            child: SingleChildScrollView(
              padding: const EdgeInsets.all(20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  // Summary Card
                  Container(
                    padding: const EdgeInsets.all(20),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: <Color>[
                          UiColors.primary.withValues(alpha: 0.05),
                          UiColors.primary.withValues(alpha: 0.1),
                        ],
                        begin: Alignment.topLeft,
                        end: Alignment.bottomRight,
                      ),
                      borderRadius: BorderRadius.circular(16),
                      border: Border.all(
                        color: UiColors.primary.withValues(alpha: 0.2),
                      ),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        _buildSummaryItem('${_positions.length}', 'Positions'),
                        _buildSummaryItem('$totalWorkers', 'Workers'),
                        _buildSummaryItem(
                          '\$${totalCost.round()}',
                          'Est. Cost',
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 20),

                  // Order Details
                  Container(
                    padding: const EdgeInsets.all(16),
                    decoration: BoxDecoration(
                      color: UiColors.white,
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(color: UiColors.separatorPrimary),
                    ),
                    child: Column(
                      children: <Widget>[
                        Row(
                          children: <Widget>[
                            const Icon(
                              UiIcons.calendar,
                              size: 16,
                              color: UiColors.primary,
                            ),
                            const SizedBox(width: 8),
                            Text(
                              _dateController.text,
                              style: UiTypography.body2m.textPrimary,
                            ),
                          ],
                        ),
                        if (_globalLocationController
                            .text
                            .isNotEmpty) ...<Widget>[
                          const SizedBox(height: 12),
                          Row(
                            children: <Widget>[
                              const Icon(
                                UiIcons.mapPin,
                                size: 16,
                                color: UiColors.primary,
                              ),
                              const SizedBox(width: 8),
                              Expanded(
                                child: Text(
                                  _globalLocationController.text,
                                  style: UiTypography.body2r.textPrimary,
                                  overflow: TextOverflow.ellipsis,
                                ),
                              ),
                            ],
                          ),
                        ],
                      ],
                    ),
                  ),
                  const SizedBox(height: 24),

                  Text(
                    'Positions Breakdown',
                    style: UiTypography.body2b.textPrimary,
                  ),
                  const SizedBox(height: 12),

                  ..._positions.map(
                    (Map<String, dynamic> pos) => _buildReviewPositionCard(pos),
                  ),

                  const SizedBox(height: 40),
                ],
              ),
            ),
          ),

          // Footer
          Container(
            padding: EdgeInsets.fromLTRB(
              UiConstants.space5,
              UiConstants.space5,
              UiConstants.space5,
              MediaQuery.of(context).padding.bottom + UiConstants.space5,
            ),
            decoration: const BoxDecoration(
              color: UiColors.white,
              border: Border(top: BorderSide(color: UiColors.border)),
            ),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: UiButton.secondary(
                    text: 'Edit',
                    onPressed: () => setState(() => _showReview = false),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: UiButton.primary(
                    text: 'Confirm & Save',
                    onPressed: () async {
                      setState(() => _isLoading = true);
                      await _saveOrderChanges();
                      if (mounted) {
                        widget.onUpdated?.call();
                        Navigator.pop(context);
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSummaryItem(String value, String label) {
    return Column(
      children: <Widget>[
        Text(
          value,
          style: UiTypography.headline2m.copyWith(
            color: UiColors.primary,
            fontWeight: FontWeight.bold,
          ),
        ),
        Text(
          label.toUpperCase(),
          style: UiTypography.titleUppercase4m.copyWith(
            color: UiColors.textSecondary,
          ),
        ),
      ],
    );
  }

  Widget _buildReviewPositionCard(Map<String, dynamic> pos) {
    final String roleId = pos['roleId']?.toString() ?? '';
    final _RoleOption? role = _roleById(roleId);
    final double rate = role?.costPerHour ?? 0;

    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: UiColors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: UiColors.separatorSecondary),
      ),
      child: Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    (role?.name ?? pos['roleName']?.toString() ?? '').isEmpty
                        ? 'Position'
                        : (role?.name ?? pos['roleName']?.toString() ?? ''),
                    style: UiTypography.body2b.textPrimary,
                  ),
                  Text(
                    '${pos['count']} worker${pos['count'] > 1 ? 's' : ''}',
                    style: UiTypography.footnote2r.textSecondary,
                  ),
                ],
              ),
              Text(
                '\$${rate.round()}/hr',
                style: UiTypography.body2b.copyWith(color: UiColors.primary),
              ),
            ],
          ),
          const SizedBox(height: 12),
          Row(
            children: <Widget>[
              const Icon(
                UiIcons.clock,
                size: 14,
                color: UiColors.iconSecondary,
              ),
              const SizedBox(width: 6),
              Text(
                '${pos['start_time']} - ${pos['end_time']}',
                style: UiTypography.footnote2r.textSecondary,
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildSuccessView() {
    return Container(
      width: double.infinity,
      height: MediaQuery.of(context).size.height * 0.95,
      decoration: const BoxDecoration(
        color: UiColors.primary,
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Container(
            width: 80,
            height: 80,
            decoration: const BoxDecoration(
              color: UiColors.accent,
              shape: BoxShape.circle,
            ),
            child: const Center(
              child: Icon(
                UiIcons.success,
                size: 40,
                color: UiColors.foreground,
              ),
            ),
          ),
          const SizedBox(height: 24),
          Text(
            'Order Updated!',
            style: UiTypography.headline1m.copyWith(color: UiColors.white),
          ),
          const SizedBox(height: 12),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: Text(
              'Your shift has been updated successfully.',
              textAlign: TextAlign.center,
              style: UiTypography.body1r.copyWith(
                color: UiColors.white.withValues(alpha: 0.7),
              ),
            ),
          ),
          const SizedBox(height: 40),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: UiButton.secondary(
              text: 'Back to Orders',
              fullWidth: true,
              style: OutlinedButton.styleFrom(
                backgroundColor: UiColors.white,
                foregroundColor: UiColors.primary,
              ),
              onPressed: () => Navigator.pop(context),
            ),
          ),
        ],
      ),
    );
  }
}
