//  SyncViewController.mm

#import "SyncScreenViewController.h"
#import "NetworkManager.h"
#import "SyncHistoryViewController.h"
#import "SyncPendingViewController.h"
#import "SyncProjectViewController.h"
#import "LocalStorage.h"
#import "OfflineSyncManager.h"
#import "SyncProgressOverlay.h"
#import "APIConfig.h"

typedef NS_ENUM(NSInteger, SyncCardType) {
    SyncCardTypeOfflineUnits = 1,
    SyncCardTypePendingItems,
    SyncCardTypeHistory
};

static NSString * const kSyncSelectedUnitsKey = @"SYNC_SELECTEDUNITS";
static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";

@interface SyncScreenViewController ()

@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;

@property (nonatomic, strong) UILabel *lastUpdatedLabel;

@property (nonatomic, strong) UIStackView *cardStack;

@property (nonatomic, strong) UIView *offlineUnitCard;
@property (nonatomic, strong) UIView *pendingItemsCard;
@property (nonatomic, strong) UIView *historyCard;

@property (nonatomic, strong) UIButton *syncButton;

@property (nonatomic, assign) NSInteger offlineUnitCount;
@property (nonatomic, assign) NSInteger pendingItemCount;
@property (nonatomic, assign) NSInteger historyCount;

@property (nonatomic, strong) NSDate *lastUpdatedDate;

@property (nonatomic, assign) BOOL isOfflineMode;
@property (nonatomic, assign) BOOL isSyncing;

@property (nonatomic, assign) BOOL shouldSubmitPending;
@property (nonatomic, assign) BOOL shouldDownloadUnits;

@property (nonatomic, strong) UIView *syncModalOverlay;
@property (nonatomic, strong) UIView *syncModalCard;

@property (nonatomic, strong) UIButton *submitPendingToggle;
@property (nonatomic, strong) UIButton *downloadUnitsToggle;

@property (nonatomic, strong) SyncProgressOverlay *progressOverlay;
@property (nonatomic, strong) UIButton *yesBtn;

@end

@implementation SyncScreenViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(networkChanged:)
                                                 name:@"NetworkStatusChanged"
                                               object:nil];

    // Initial connectivity check
    self.isOfflineMode = ![[NetworkManager sharedManager] isConnected];
    
    self.view.backgroundColor = UIColor.whiteColor;
    self.isSyncing = NO;
  
    //placeholders
    self.pendingItemCount = 1;
    self.offlineUnitCount = 1;
    self.historyCount = 1;
  
    [self setupHeader];
    [self setupSyncButton];
    [self setupMainContent];

    [self refreshUI];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.pendingItemCount = [self loadPendingItemCount];
    self.offlineUnitCount = [self loadOfflineUnitCount];
    self.historyCount = [self loadHistoryItemCount];
  
    [self refreshUI];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                               name:@"NetworkStatusChanged"
                                             object:nil];
}

#pragma mark - Refresh
-(void)refreshUI {
  [self updateLastUpdatedLabel];
  [self updateCards];
  [self updateSyncButton];
}

- (void)updateSyncButton {
    BOOL hasData =
        self.offlineUnitCount > 0 ||
        self.pendingItemCount > 0 ||
        self.historyCount > 0;

    BOOL enabled =
        !self.isOfflineMode &&
        !self.isSyncing &&
        hasData;

    self.syncButton.enabled = enabled;
    self.syncButton.alpha = enabled ? 1.0 : 0.4;
}

- (void)updateCards {
    [self updateCard:self.offlineUnitCard count:self.offlineUnitCount];
    [self updateCard:self.pendingItemsCard count:self.pendingItemCount];
    [self updateCard:self.historyCard count:self.historyCount];
}

- (void)updateLastUpdatedLabel {
    NSString *dateString = [self lastSyncDisplayString];
    self.lastUpdatedLabel.text =
        [NSString stringWithFormat:@"Last Updated:\n%@", dateString];
}

#pragma mark - Header
- (void)setupHeader {
    self.headerView = [[UIView alloc] init];
    self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
    self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.headerView];

    self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"]
                     forState:UIControlStateNormal];
    [self.backButton addTarget:self
                        action:@selector(onBack)
              forControlEvents:UIControlEventTouchUpInside];
    self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
    self.backButton.tintColor = UIColor.whiteColor;
    [self.headerView addSubview:self.backButton];

    self.titleLabel = [[UILabel alloc] init];
    self.titleLabel.text = @"Sync";
    self.titleLabel.textColor = UIColor.whiteColor;
    self.titleLabel.font = [UIFont boldSystemFontOfSize:18];
    self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.headerView addSubview:self.titleLabel];

    // Constraints
    [NSLayoutConstraint activateConstraints:@[
        [self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
        [self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.headerView.heightAnchor constraintEqualToConstant:48],

        [self.backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
        [self.backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
        [self.backButton.widthAnchor constraintEqualToConstant:32],
        [self.backButton.heightAnchor constraintEqualToConstant:32],

        [self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
        [self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
    ]];
}

#pragma mark - Main Content
- (void)setupMainContent {
    UIView *content = [[UIView alloc] init];
    content.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:content];

    [NSLayoutConstraint activateConstraints:@[
        [content.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:16],
        [content.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
        [content.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
        [content.bottomAnchor constraintEqualToAnchor:self.syncButton.topAnchor constant:-16],
    ]];

    // Last Updated
    self.lastUpdatedLabel = [[UILabel alloc] init];
    self.lastUpdatedLabel.numberOfLines = 2;
    self.lastUpdatedLabel.text = @"Last Updated:\n--";
    self.lastUpdatedLabel.textColor = [UIColor grayColor];
    self.lastUpdatedLabel.font = [UIFont boldSystemFontOfSize:16];
    self.lastUpdatedLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [content addSubview:self.lastUpdatedLabel];

    [NSLayoutConstraint activateConstraints:@[
        [self.lastUpdatedLabel.topAnchor constraintEqualToAnchor:content.topAnchor],
        [self.lastUpdatedLabel.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
        [self.lastUpdatedLabel.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
    ]];

    // Cards Stack
    self.cardStack = [[UIStackView alloc] init];
    self.cardStack.axis = UILayoutConstraintAxisVertical;
    self.cardStack.spacing = 16;
    self.cardStack.translatesAutoresizingMaskIntoConstraints = NO;
    [content addSubview:self.cardStack];

    [NSLayoutConstraint activateConstraints:@[
        [self.cardStack.topAnchor constraintEqualToAnchor:self.lastUpdatedLabel.bottomAnchor constant:16],
        [self.cardStack.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
        [self.cardStack.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
    ]];

    // Add 3 cards
    self.offlineUnitCard = [self createCardWithTitle:@"Offline Units"];
    self.pendingItemsCard = [self createCardWithTitle:@"Pending Items"];
    self.historyCard = [self createCardWithTitle:@"History"];
    
    self.offlineUnitCard.userInteractionEnabled = YES;
    self.pendingItemsCard.userInteractionEnabled = YES;
    self.historyCard.userInteractionEnabled = YES;
  
    self.offlineUnitCard = [self createCardWithTitle:@"Offline Units"];
    self.offlineUnitCard.tag = SyncCardTypeOfflineUnits;

    self.pendingItemsCard = [self createCardWithTitle:@"Pending Items"];
    self.pendingItemsCard.tag = SyncCardTypePendingItems;

    self.historyCard = [self createCardWithTitle:@"History"];
    self.historyCard.tag = SyncCardTypeHistory;

    [self addTapToCard:self.offlineUnitCard action:@selector(onOfflineUnitsTapped)];
    [self addTapToCard:self.pendingItemsCard action:@selector(onPendingItemsTapped)];
    [self addTapToCard:self.historyCard action:@selector(onHistoryTapped)];

    [self.cardStack addArrangedSubview:self.offlineUnitCard];
    [self.cardStack addArrangedSubview:self.pendingItemsCard];
    [self.cardStack addArrangedSubview:self.historyCard];
}

#pragma mark - Card Factory
- (UIView *)createCardWithTitle:(NSString *)title {
    UIView *card = [[UIView alloc] init];
    card.backgroundColor = UIColor.whiteColor;
    card.layer.borderWidth = 1;
    card.layer.borderColor = [UIColor lightGrayColor].CGColor;
    card.layer.cornerRadius = 10;
    card.translatesAutoresizingMaskIntoConstraints = NO;

    [NSLayoutConstraint activateConstraints:@[
        [card.heightAnchor constraintEqualToConstant:120]
    ]];

    UILabel *titleLabel = [[UILabel alloc] init];
    titleLabel.text = title;
    titleLabel.font = [UIFont boldSystemFontOfSize:20];
    titleLabel.textColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
    titleLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UILabel *countLabel = [[UILabel alloc] init];
    countLabel.text = @"0";
    countLabel.font = [UIFont boldSystemFontOfSize:28];
    countLabel.textColor = titleLabel.textColor;
    countLabel.textAlignment = NSTextAlignmentRight;
    countLabel.translatesAutoresizingMaskIntoConstraints = NO;

    countLabel.tag = 1001; // IMPORTANT

    [card addSubview:titleLabel];
    [card addSubview:countLabel];

    [NSLayoutConstraint activateConstraints:@[
        [titleLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
        [titleLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:16],

        [countLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-16],
        [countLabel.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-16],
    ]];

    return card;
}

- (void)updateCard:(UIView *)card count:(NSInteger)count {
    UILabel *countLabel = [card viewWithTag:1001];
    countLabel.text = [NSString stringWithFormat:@"%ld", (long)count];

    // 🔥 Offline Units should always be enabled
    if (card.tag == SyncCardTypeOfflineUnits) {
        card.alpha = 1.0;
        card.userInteractionEnabled = YES;
        return;
    }

    // Default behaviour for others
    BOOL enabled = count > 0;
    card.alpha = enabled ? 1.0 : 0.4;
    card.userInteractionEnabled = enabled;
}

#pragma mark - Sync Button
- (void)setupSyncButton {
    self.syncButton = [UIButton buttonWithType:UIButtonTypeSystem];
    self.syncButton.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
    [self.syncButton setTitle:@"SYNC" forState:UIControlStateNormal];
    [self.syncButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
    self.syncButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
    self.syncButton.layer.cornerRadius = 8;
    self.syncButton.translatesAutoresizingMaskIntoConstraints = NO;

    [self.syncButton addTarget:self
                        action:@selector(onSyncTapped)
              forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:self.syncButton];

    [NSLayoutConstraint activateConstraints:@[
        [self.syncButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
        [self.syncButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
        [self.syncButton.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-16],
        [self.syncButton.heightAnchor constraintEqualToConstant:50],
    ]];
}

#pragma mark - Sync Modal
- (void)showSyncConfirmationModal {
    if (self.syncModalOverlay) return; // already showing

    self.shouldSubmitPending  = NO;
    self.shouldDownloadUnits  = NO;

    [self buildSyncModal];
}

- (void)buildSyncModal {
    // --- Overlay ---
    self.syncModalOverlay = [[UIView alloc] initWithFrame:self.view.bounds];
    self.syncModalOverlay.backgroundColor =
        [[UIColor blackColor] colorWithAlphaComponent:0.5];
    self.syncModalOverlay.autoresizingMask =
        UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.view addSubview:self.syncModalOverlay];

    // --- Card ---
    self.syncModalCard = [[UIView alloc] init];
    self.syncModalCard.backgroundColor = UIColor.whiteColor;
    self.syncModalCard.layer.cornerRadius = 12;
    self.syncModalCard.translatesAutoresizingMaskIntoConstraints = NO;
    [self.syncModalOverlay addSubview:self.syncModalCard];

    [NSLayoutConstraint activateConstraints:@[
        [self.syncModalCard.centerXAnchor constraintEqualToAnchor:self.syncModalOverlay.centerXAnchor],
        [self.syncModalCard.centerYAnchor constraintEqualToAnchor:self.syncModalOverlay.centerYAnchor],
        [self.syncModalCard.widthAnchor constraintEqualToConstant:280]
    ]];

    // --- Title ---
    UILabel *title = [[UILabel alloc] init];
    title.text = @"Sync";
    title.font = [UIFont boldSystemFontOfSize:18];
    title.textAlignment = NSTextAlignmentCenter;
    title.translatesAutoresizingMaskIntoConstraints = NO;
    [self.syncModalCard addSubview:title];

    // --- Message ---
    UILabel *message = [[UILabel alloc] init];
    message.text = @"Synchronize?";
    message.font = [UIFont systemFontOfSize:14];
    message.textAlignment = NSTextAlignmentCenter;
    message.translatesAutoresizingMaskIntoConstraints = NO;
    [self.syncModalCard addSubview:message];

    // --- Toggles ---
    self.submitPendingToggle =
        [self createToggleWithTitle:@"Submit all pending"
                           selected:NO
                             action:@selector(onSubmitPendingToggle)];

    self.downloadUnitsToggle =
        [self createToggleWithTitle:@"Download all selected units"
                           selected:NO
                             action:@selector(onDownloadUnitsToggle)];

    // --- Buttons ---
    UIButton *noBtn = [self modalButton:@"NO" action:@selector(onSyncModalNo)];
    self.yesBtn = [self modalButton:@"YES" action:@selector(onSyncModalYes)];
  
    self.yesBtn.enabled = self.shouldSubmitPending || self.shouldDownloadUnits;
    self.yesBtn.alpha = self.yesBtn.enabled ? 1.0 : 0.5;

    // --- Layout ---
    UIStackView *stack = [[UIStackView alloc] initWithArrangedSubviews:@[
        title,
        message,
        self.submitPendingToggle,
        self.downloadUnitsToggle,
        noBtn,
        self.yesBtn
    ]];

    stack.axis = UILayoutConstraintAxisVertical;
    stack.spacing = 12;
    stack.translatesAutoresizingMaskIntoConstraints = NO;
    [self.syncModalCard addSubview:stack];

    [NSLayoutConstraint activateConstraints:@[
        [stack.topAnchor constraintEqualToAnchor:self.syncModalCard.topAnchor constant:16],
        [stack.leadingAnchor constraintEqualToAnchor:self.syncModalCard.leadingAnchor constant:16],
        [stack.trailingAnchor constraintEqualToAnchor:self.syncModalCard.trailingAnchor constant:-16],
        [stack.bottomAnchor constraintEqualToAnchor:self.syncModalCard.bottomAnchor constant:-16],
    ]];
}

- (UIButton *)createToggleWithTitle:(NSString *)title
                           selected:(BOOL)selected
                             action:(SEL)action {

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
    btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    btn.titleLabel.font = [UIFont systemFontOfSize:14];

    [btn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
    [btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];

    btn.selected = selected;
    [self updateToggleAppearance:btn title:title];

    return btn;
}

#pragma mark - Progress Overlay
- (void)showProgressOverlay {
    if (self.progressOverlay) return;

    self.progressOverlay =
        [[SyncProgressOverlay alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:self.progressOverlay];
}

#pragma mark - Helpers
- (void)onBack {
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)addTapToCard:(UIView *)card action:(SEL)selector {
    UITapGestureRecognizer *tap =
        [[UITapGestureRecognizer alloc] initWithTarget:self action:selector];
    tap.cancelsTouchesInView = YES;
    [card addGestureRecognizer:tap];
    card.userInteractionEnabled = YES; // actual enable/disable happens later
}

- (void)onOfflineUnitsTapped {
    NSLog(@"Offline Units tapped");
  
    SyncProjectViewController *nextVC = [[SyncProjectViewController alloc] init];
    nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:nextVC animated:YES completion:nil];
}

- (void)onPendingItemsTapped {
    if (self.pendingItemCount == 0) return;
    NSLog(@"Pending Items tapped");
  
    SyncPendingViewController *nextVC = [[SyncPendingViewController alloc] init];
    nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:nextVC animated:YES completion:nil];
}

- (void)onHistoryTapped {
    if (self.historyCount == 0) return;
    NSLog(@"History tapped");
  
    SyncHistoryViewController *nextVC = [[SyncHistoryViewController alloc] init];
    nextVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:nextVC animated:YES completion:nil];
}

- (void)onSyncTapped {
    if (self.isOfflineMode || self.isSyncing) return;
    [self showSyncConfirmationModal];
}

- (void)onSubmitPendingToggle {
    self.shouldSubmitPending = !self.shouldSubmitPending;
    self.submitPendingToggle.selected = self.shouldSubmitPending;
    [self updateToggleAppearance:self.submitPendingToggle title:@"Submit all pending"];
    [self updateYesButtonState];
}

- (void)onDownloadUnitsToggle {
    self.shouldDownloadUnits = !self.shouldDownloadUnits;
    self.downloadUnitsToggle.selected = self.shouldDownloadUnits;
    [self updateToggleAppearance:self.downloadUnitsToggle title:@"Download all selected units"];
    [self updateYesButtonState];
}

- (void)updateToggleAppearance:(UIButton *)btn title:(NSString *)title {
    NSString *prefix = btn.selected ? @"☑︎ " : @"☐ ";
    [btn setTitle:[prefix stringByAppendingString:title] forState:UIControlStateNormal];
}

- (UIButton *)modalButton:(NSString *)title action:(SEL)action {
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
    btn.layer.cornerRadius = 6;
    btn.backgroundColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0];
    [btn setTitle:title forState:UIControlStateNormal];
    [btn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
    btn.titleLabel.font = [UIFont boldSystemFontOfSize:14];
    [btn addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    return btn;
}

- (void)onSyncModalNo {
    [self dismissSyncModal];
}

- (void)onSyncModalYes {
    [self dismissSyncModal];

    self.isSyncing = YES;
    [self refreshUI];
    [self showProgressOverlay];

    __weak typeof(self) weakSelf = self;

    // 1️⃣ Manual pending sync
    if (self.shouldSubmitPending) {
        NSLog(@"Syncing Pending Items");
      
        NSString *message = [NSString stringWithFormat:
                           @"Currently uploading pending items.\nPlease do not close the app."];

          [[OfflineSyncManager shared]
           processNextItemWithProgress:^(NSInteger step, NSInteger total, NSString *title) {
            NSLog(@"📊 progress %ld/%ld %@", (long)step, (long)total, title);
            [self.progressOverlay updateStep:step
                                       total:total
                                     message:message];

           } completion:^(BOOL finished) {
           NSLog(@"🎉 Offline sync COMPLETED finished=%d", finished);
           self.pendingItemCount = [self loadPendingItemCount];
           self.historyCount = [self loadHistoryItemCount];
             
           if (!self.shouldDownloadUnits) {
               [self finishSyncWithSuccess:finished];
           }
             
           [self refreshUI];
         }];
    }

    // 2️⃣ Unit + image download sync
    if (self.shouldDownloadUnits) {
        __weak typeof(self) weakSelf = self;

        NSArray *selectedUnits = [LocalStorage loadArrayForKey:kSyncSelectedUnitsKey] ?: @[];
        if (selectedUnits.count == 0) {
            NSLog(@"⚠️ No units found in local storage for %@", kSyncSelectedUnitsKey);
            [self finishSyncWithSuccess:YES];
            return;
        }

        NSString *originalProjectId = [APIConfig projectId];
        NSString *originalDrawingPlanId = [APIConfig drawingPlanId];

        NSLog(@"📦 [LocalStorage] %@ = %@", kSyncSelectedUnitsKey, selectedUnits);

        // 1️⃣ Calculate total tasks (sum of image counts in all units)
        __block NSInteger totalTasks = 0;
        for (NSDictionary *unit in selectedUnits) {
            NSInteger imageCount = [unit[@"image_count"] integerValue] ?: 1; // fallback to 1 if missing
            totalTasks += imageCount;
        }
        __block NSInteger completedTasks = 0;
        __block NSInteger currentUnitIndex = 0;
        __block void (^runNextUnit)(void);

        runNextUnit = ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (!strongSelf) return;

            if (currentUnitIndex >= selectedUnits.count) {
                // Restore original APIConfig
                [APIConfig setProjectId:originalProjectId];
                [APIConfig setDrawingPlanId:originalDrawingPlanId];

                NSLog(@"✅ All units downloaded");
                [strongSelf finishSyncWithSuccess:YES];
                return;
            }

            NSDictionary *unit = selectedUnits[currentUnitIndex];
            currentUnitIndex++;

            NSString *projectId = unit[@"project"][@"id"];
            NSString *planId = unit[@"plan_id"];
            NSString *sortName = unit[@"sort_name"] ?: @"(unknown)";

            if (!projectId || !planId) {
                NSLog(@"⚠️ Missing project_id or plan_id at index %ld: %@", (long)currentUnitIndex, unit);
                runNextUnit(); // skip invalid
                return;
            }

            [APIConfig setProjectId:projectId];
            [APIConfig setDrawingPlanId:planId];

            NSLog(@"➡️ Downloading unit %ld / %lu: projectId=%@, drawingPlanId=%@",
                  (long)currentUnitIndex, (unsigned long)selectedUnits.count,
                  [APIConfig projectId], [APIConfig drawingPlanId]);

            NSString *message = [NSString stringWithFormat:
                                 @"Currently downloading for unit \"%@\".\nPlease do not close the app.", sortName];

            [[OfflineSyncManager shared] startDownloadUnitImagesWithProgress:^(NSInteger completed, NSInteger total) {
                __strong typeof(weakSelf) strongSelf2 = weakSelf;
                if (!strongSelf2) return;

                // Update overlay with progress number and message
                [strongSelf2.progressOverlay updateStep:completed
                                                 total:total
                                               message:message];

            } completion:^(BOOL success) {
                __strong typeof(weakSelf) strongSelf2 = weakSelf;
                if (!strongSelf2) return;

                if (!success) {
                    NSLog(@"⚠️ Unit download failed: projectId=%@, drawingPlanId=%@", projectId, planId);
                }

                // Continue to next unit
                runNextUnit();
            }];
        };

        // Start first unit
        runNextUnit();
    }
}

- (void)dismissSyncModal {
    [self.syncModalOverlay removeFromSuperview];
    self.syncModalOverlay = nil;
    self.syncModalCard = nil;
}

- (void)networkChanged:(NSNotification *)notif {
    BOOL connected = [notif.userInfo[@"connected"] boolValue];
    self.isOfflineMode = !connected;

    NSLog(@"Network changed: %@", connected ? @"YES" : @"NO");

    [self refreshUI];
}

- (NSInteger)loadPendingItemCount {
    NSArray *queue = [LocalStorage loadArrayForKey:@"OFFLINE_SYNC_QUEUE"];
    return queue.count;
}

- (NSInteger)loadOfflineUnitCount {
    NSArray *units = [LocalStorage loadArrayForKey:kSyncSelectedUnitsKey];
    return units.count;
}

- (NSInteger)loadHistoryItemCount {
    NSArray *units = [LocalStorage loadArrayForKey:@"SYNC_HISTORY_QUEUE"];
    return units.count;
}

- (void)finishSyncWithSuccess:(BOOL)success {
    [self.progressOverlay removeFromSuperview];
    self.progressOverlay = nil;

    self.isSyncing = NO;

    if (success) {
        self.lastUpdatedDate = [NSDate date];
    }

    [self refreshUI];
}

- (NSString *)lastSyncDisplayString {

    NSNumber *ts = [LocalStorage loadObjectForKey:kLastOfflineSyncDateKey];
    if (!ts) {
        return @"--";
    }

    NSDate *date = [NSDate dateWithTimeIntervalSince1970:ts.doubleValue];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateStyle = NSDateFormatterMediumStyle;
    formatter.timeStyle = NSDateFormatterShortStyle;

    return [formatter stringFromDate:date];
}

- (void)updateYesButtonState {
    BOOL enabled = self.shouldSubmitPending || self.shouldDownloadUnits;
    self.yesBtn.enabled = enabled;
    self.yesBtn.alpha = enabled ? 1.0 : 0.5;
}

@end
