// SyncProjectViewController.mm
#import "SyncProjectViewController.h"
#import "LocalStorage.h"

typedef NS_ENUM(NSInteger, SyncProjectScreenState) {
    SyncProjectScreenStateOfflineUnit,
    SyncProjectScreenStateSelectProject,
    SyncProjectScreenStateSelectUnit
};

static NSString * const kSyncSelectedUnitsKey = @"SYNC_SELECTEDUNITS";
static NSString * const kProjectListKey = @"PROJECT_LIST";

@interface SyncUnit : NSObject
@property (nonatomic, strong) NSString *planId;
@property (nonatomic, strong) NSString *displayName;
@property (nonatomic, strong) NSString *projectId;
@property (nonatomic, strong) NSString *projectName;
@property (nonatomic, assign) BOOL selected;
@end

@implementation SyncUnit
@end

@interface SyncProject : NSObject
@property (nonatomic, strong) NSString *projectId;
@property (nonatomic, strong) NSString *projectName;
@property (nonatomic, strong) NSArray<SyncUnit *> *units;
@end

@implementation SyncProject
@end

@interface SyncProjectViewController ()
<
UITableViewDelegate,
UITableViewDataSource,
UICollectionViewDelegate,
UICollectionViewDataSource
>

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

// Content containers
@property (nonatomic, strong) UIView *offlineUnitView;
@property (nonatomic, strong) UIView *selectProjectView;
@property (nonatomic, strong) UIView *selectUnitView;

// Common UI
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIActivityIndicatorView *loadingView;

// State
@property (nonatomic, assign) NSInteger selectedUnitCount;

@property (nonatomic, assign) SyncProjectScreenState screenState;
@property (nonatomic, assign) BOOL hasChanges;
@property (nonatomic, strong) NSMutableArray<SyncUnit *> *selectedUnits;

@property (nonatomic, strong) NSMutableArray<SyncProject *> *dummyProjects;
@property (nonatomic, strong) NSMutableArray<SyncUnit *> *dummyUnits;

@property (nonatomic, strong) UITableView *offlineTableView;
@property (nonatomic, strong) UITableView *unitTableView;
@property (nonatomic, strong) UICollectionView *projectCollectionView;

@end


@implementation SyncProjectViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor systemGroupedBackgroundColor];
    self.selectedUnitCount = 0;
    self.selectedUnits = [NSMutableArray array];
    [self loadSelectedUnits];
    [self setupDummyData];

    [self setupHeader];
    [self setupContentContainers];
    [self setupOfflineUnitView];
    [self setupSelectProjectView];
    [self setupSelectUnitView];

    [self showOfflineUnit];
    [self setScreenState:SyncProjectScreenStateOfflineUnit];
}

#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 = @"Offline Unit";
    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],
    ]];
}

- (void)setHeaderTitle:(NSString *)title {
    self.titleLabel.text = title;
}

#pragma mark - Setup ContentContainer
- (void)setupContentContainers {
    self.offlineUnitView = [UIView new];
    self.selectProjectView = [UIView new];
    self.selectUnitView = [UIView new];

    NSArray *views = @[self.offlineUnitView, self.selectProjectView, self.selectUnitView];

    for (UIView *v in views) {
        v.translatesAutoresizingMaskIntoConstraints = NO;
        v.hidden = YES;
        [self.view addSubview:v];

        [NSLayoutConstraint activateConstraints:@[
            [v.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
            [v.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
            [v.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
            [v.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
        ]];
    }
}

#pragma mark - Offline Unit View
- (void)setupOfflineUnitView {

    UILabel *countLabel = [UILabel new];
    countLabel.font = [UIFont boldSystemFontOfSize:24];
    countLabel.text = @"NO UNITS SELECTED";
    countLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UIButton *addButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [addButton setImage:[UIImage systemImageNamed:@"plus.circle.fill"]
               forState:UIControlStateNormal];
    addButton.tintColor = [UIColor systemTealColor];
    addButton.translatesAutoresizingMaskIntoConstraints = NO;
    [addButton addTarget:self
                  action:@selector(onAddUnit)
        forControlEvents:UIControlEventTouchUpInside];

    UILabel *infoLabel = [UILabel new];
    infoLabel.text = @"Maximum 10 units";
    infoLabel.font = [UIFont systemFontOfSize:16];
    infoLabel.translatesAutoresizingMaskIntoConstraints = NO;

    self.offlineTableView =
        [[UITableView alloc] initWithFrame:CGRectZero
                                     style:UITableViewStyleGrouped];
    self.offlineTableView.translatesAutoresizingMaskIntoConstraints = NO;
    self.offlineTableView.delegate = self;
    self.offlineTableView.dataSource = self;
    [self.offlineTableView registerClass:UITableViewCell.class
                  forCellReuseIdentifier:@"OfflineUnitCell"];


    [self.offlineUnitView addSubview:countLabel];
    [self.offlineUnitView addSubview:addButton];
    [self.offlineUnitView addSubview:infoLabel];
    [self.offlineUnitView addSubview:self.offlineTableView];

    [NSLayoutConstraint activateConstraints:@[
        [countLabel.topAnchor constraintEqualToAnchor:self.offlineUnitView.topAnchor constant:16],
        [countLabel.leadingAnchor constraintEqualToAnchor:self.offlineUnitView.leadingAnchor constant:16],

        [addButton.trailingAnchor constraintEqualToAnchor:self.offlineUnitView.trailingAnchor constant:-16],
        [addButton.centerYAnchor constraintEqualToAnchor:countLabel.centerYAnchor],
        [addButton.widthAnchor constraintEqualToConstant:36],
        [addButton.heightAnchor constraintEqualToConstant:36],

        [infoLabel.topAnchor constraintEqualToAnchor:countLabel.bottomAnchor constant:12],
        [infoLabel.leadingAnchor constraintEqualToAnchor:countLabel.leadingAnchor],

        [self.offlineTableView.topAnchor constraintEqualToAnchor:infoLabel.bottomAnchor constant:12],
       [self.offlineTableView.leadingAnchor constraintEqualToAnchor:self.offlineUnitView.leadingAnchor],
       [self.offlineTableView.trailingAnchor constraintEqualToAnchor:self.offlineUnitView.trailingAnchor],
       [self.offlineTableView.bottomAnchor constraintEqualToAnchor:self.offlineUnitView.bottomAnchor],
    ]];
}

#pragma mark - Select Project View
- (void)setupSelectProjectView {

    UILabel *countLabel = [UILabel new];
    countLabel.font = [UIFont boldSystemFontOfSize:24];
    countLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UILabel *instructionLabel = [UILabel new];
    instructionLabel.text = @"Please select project";
    instructionLabel.font = [UIFont systemFontOfSize:18];
    instructionLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UISearchBar *searchBar = [UISearchBar new];
    searchBar.translatesAutoresizingMaskIntoConstraints = NO;

    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.itemSize = CGSizeMake(self.view.bounds.size.width - 32, 120);
    layout.minimumLineSpacing = 12;

    self.projectCollectionView =
        [[UICollectionView alloc] initWithFrame:CGRectZero
                           collectionViewLayout:layout];
    self.projectCollectionView.translatesAutoresizingMaskIntoConstraints = NO;
    self.projectCollectionView.backgroundColor = UIColor.clearColor;
    self.projectCollectionView.delegate = self;
    self.projectCollectionView.dataSource = self;
    [self.projectCollectionView registerClass:UICollectionViewCell.class
                   forCellWithReuseIdentifier:@"ProjectCell"];

    [self.selectProjectView addSubview:countLabel];
    [self.selectProjectView addSubview:instructionLabel];
    [self.selectProjectView addSubview:searchBar];
    [self.selectProjectView addSubview:self.projectCollectionView];

    [NSLayoutConstraint activateConstraints:@[
        [countLabel.topAnchor constraintEqualToAnchor:self.selectProjectView.topAnchor constant:16],
        [countLabel.leadingAnchor constraintEqualToAnchor:self.selectProjectView.leadingAnchor constant:16],

        [instructionLabel.topAnchor constraintEqualToAnchor:countLabel.bottomAnchor constant:8],
        [instructionLabel.leadingAnchor constraintEqualToAnchor:countLabel.leadingAnchor],

        [searchBar.topAnchor constraintEqualToAnchor:instructionLabel.bottomAnchor constant:8],
        [searchBar.leadingAnchor constraintEqualToAnchor:self.selectProjectView.leadingAnchor],
        [searchBar.trailingAnchor constraintEqualToAnchor:self.selectProjectView.trailingAnchor],

        [self.projectCollectionView.topAnchor constraintEqualToAnchor:searchBar.bottomAnchor constant:8],
        [self.projectCollectionView.leadingAnchor constraintEqualToAnchor:self.selectProjectView.leadingAnchor],
        [self.projectCollectionView.trailingAnchor constraintEqualToAnchor:self.selectProjectView.trailingAnchor],
        [self.projectCollectionView.bottomAnchor constraintEqualToAnchor:self.selectProjectView.bottomAnchor],
    ]];
}

#pragma mark - Select Unit View
- (void)setupSelectUnitView {

    UILabel *countLabel = [UILabel new];
    countLabel.font = [UIFont boldSystemFontOfSize:24];
    countLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UILabel *instructionLabel = [UILabel new];
    instructionLabel.text = @"Please select a unit";
    instructionLabel.translatesAutoresizingMaskIntoConstraints = NO;

    UISearchBar *searchBar = [UISearchBar new];
    searchBar.translatesAutoresizingMaskIntoConstraints = NO;

    self.unitTableView = [[UITableView alloc] init];
    self.unitTableView.translatesAutoresizingMaskIntoConstraints = NO;
    self.unitTableView.delegate = self;
    self.unitTableView.dataSource = self;
    [self.unitTableView registerClass:UITableViewCell.class
               forCellReuseIdentifier:@"UnitCell"];

    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [doneButton setTitle:@"DONE" forState:UIControlStateNormal];
    doneButton.backgroundColor = [UIColor systemTealColor];
    doneButton.tintColor = UIColor.whiteColor;
    doneButton.layer.cornerRadius = 8;
    doneButton.translatesAutoresizingMaskIntoConstraints = NO;
    [doneButton addTarget:self
                   action:@selector(onDone)
         forControlEvents:UIControlEventTouchUpInside];

    [self.selectUnitView addSubview:countLabel];
    [self.selectUnitView addSubview:instructionLabel];
    [self.selectUnitView addSubview:searchBar];
    [self.selectUnitView addSubview:self.unitTableView];
    [self.selectUnitView addSubview:doneButton];

    [NSLayoutConstraint activateConstraints:@[
        [countLabel.topAnchor constraintEqualToAnchor:self.selectUnitView.topAnchor constant:16],
        [countLabel.leadingAnchor constraintEqualToAnchor:self.selectUnitView.leadingAnchor constant:16],

        [instructionLabel.topAnchor constraintEqualToAnchor:countLabel.bottomAnchor constant:8],
        [instructionLabel.leadingAnchor constraintEqualToAnchor:countLabel.leadingAnchor],

        [searchBar.topAnchor constraintEqualToAnchor:instructionLabel.bottomAnchor constant:8],
        [searchBar.leadingAnchor constraintEqualToAnchor:self.selectUnitView.leadingAnchor],
        [searchBar.trailingAnchor constraintEqualToAnchor:self.selectUnitView.trailingAnchor],

        [self.unitTableView.topAnchor constraintEqualToAnchor:searchBar.bottomAnchor constant:8],
        [self.unitTableView.leadingAnchor constraintEqualToAnchor:self.selectUnitView.leadingAnchor],
        [self.unitTableView.trailingAnchor constraintEqualToAnchor:self.selectUnitView.trailingAnchor],

        [doneButton.topAnchor constraintEqualToAnchor:self.unitTableView.bottomAnchor constant:12],
        [doneButton.leadingAnchor constraintEqualToAnchor:self.selectUnitView.leadingAnchor constant:16],
        [doneButton.trailingAnchor constraintEqualToAnchor:self.selectUnitView.trailingAnchor constant:-16],
        [doneButton.heightAnchor constraintEqualToConstant:48],
        [doneButton.bottomAnchor constraintEqualToAnchor:self.selectUnitView.bottomAnchor constant:-16],
    ]];
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (tableView == self.offlineTableView) {
        return self.dummyUnits.count;
    }

    if (tableView == self.unitTableView) {
        return self.dummyUnits.count;
    }

    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell;

    if (tableView == self.offlineTableView) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"OfflineUnitCell"
                                               forIndexPath:indexPath];
    } else {
        cell = [tableView dequeueReusableCellWithIdentifier:@"UnitCell"
                                               forIndexPath:indexPath];
    }

    SyncUnit *unit = self.dummyUnits[indexPath.row];
    cell.textLabel.text = unit.displayName;
    cell.accessoryType = unit.selected
        ? UITableViewCellAccessoryCheckmark
        : UITableViewCellAccessoryNone;

    return cell;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    SyncUnit *unit = self.dummyUnits[indexPath.row];
    [self toggleUnit:unit];

    [tableView reloadRowsAtIndexPaths:@[indexPath]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
}

#pragma mark - UICollectionViewDataSource

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section {
    return self.dummyProjects.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                           cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell =
        [collectionView dequeueReusableCellWithReuseIdentifier:@"ProjectCell"
                                                  forIndexPath:indexPath];

    cell.contentView.backgroundColor = UIColor.systemGray6Color;
    cell.layer.cornerRadius = 12;

    UILabel *label = [cell.contentView viewWithTag:100];
    if (!label) {
        label = [[UILabel alloc] initWithFrame:cell.contentView.bounds];
        label.tag = 100;
        label.font = [UIFont boldSystemFontOfSize:16];
        label.textAlignment = NSTextAlignmentCenter;
        [cell.contentView addSubview:label];
    }

    SyncProject *project = self.dummyProjects[indexPath.item];
    label.text = project.projectName;

    return cell;
}

#pragma mark - Screen State
- (void)setScreenState:(SyncProjectScreenState)state {
    _screenState = state;

    self.offlineUnitView.hidden = YES;
    self.selectProjectView.hidden = YES;
    self.selectUnitView.hidden = YES;

    switch (state) {
        case SyncProjectScreenStateOfflineUnit:
            self.offlineUnitView.hidden = NO;
            [self.offlineTableView reloadData];
            break;

        case SyncProjectScreenStateSelectProject:
            self.selectProjectView.hidden = NO;
            [self.projectCollectionView reloadData];
            break;

        case SyncProjectScreenStateSelectUnit:
            self.selectUnitView.hidden = NO;
            [self.unitTableView reloadData];
            break;
    }
}

#pragma mark - Helpers
- (void)onBack {
    switch (self.screenState) {
        case SyncProjectScreenStateOfflineUnit:
            [self dismissViewControllerAnimated:YES completion:nil];
            break;
        
        case SyncProjectScreenStateSelectProject:
            [self setScreenState:SyncProjectScreenStateOfflineUnit];
            break;

        case SyncProjectScreenStateSelectUnit:
            [self setScreenState:SyncProjectScreenStateSelectProject];
            break;
    }
}

- (void)hideAllContent {
    self.offlineUnitView.hidden = YES;
    self.selectProjectView.hidden = YES;
    self.selectUnitView.hidden = YES;
}

- (void)showOfflineUnit {
    [self hideAllContent];
    [self setHeaderTitle:@"Offline Unit"];
    self.offlineUnitView.hidden = NO;
}

- (void)showSelectProject {
    [self hideAllContent];
    [self setHeaderTitle:@"Add Unit"];
    self.selectProjectView.hidden = NO;
}

- (void)showSelectUnit {
    [self hideAllContent];
    [self setHeaderTitle:@"Add Unit"];
    self.selectUnitView.hidden = NO;
}

- (void)onAddUnit {
    [self showSelectProject];
}

- (void)onDone {
    [self showOfflineUnit];
}

- (BOOL)canAddUnit {
    return self.selectedUnits.count < 10;
}

- (void)toggleUnit:(SyncUnit *)unit {
    if (unit.selected) {
        unit.selected = NO;
        [self.selectedUnits removeObject:unit];
    } else {
        if (![self canAddUnit]) {
          NSLog(@"only 10 units recommended");
          return;
        }
        unit.selected = YES;
        [self.selectedUnits addObject:unit];
    }

    self.hasChanges = YES;
    self.selectedUnitCount = self.selectedUnits.count;

    [self saveSelectedUnits];
}

- (void)showLoading:(BOOL)show {
    if (show) {
        [self.loadingView startAnimating];
    } else {
        [self.loadingView stopAnimating];
    }
}

- (NSDictionary *)dictionaryFromUnit:(SyncUnit *)unit {
    return @{
        @"plan_id": unit.planId ?: @"",
        @"sort_name": unit.displayName ?: @"",
        @"project": @{
            @"id": unit.projectId ?: @"",
            @"project_name": unit.projectName ?: @""
        }
    };
}

- (SyncUnit *)unitFromDictionary:(NSDictionary *)dict {
    SyncUnit *unit = [SyncUnit new];
    unit.planId = dict[@"plan_id"];
    unit.displayName = dict[@"sort_name"];

    NSDictionary *project = dict[@"project"];
    unit.projectId = project[@"id"];
    unit.projectName = project[@"project_name"];

    unit.selected = YES;
    return unit;
}

- (void)saveSelectedUnits {
    NSMutableArray *array = [NSMutableArray array];

    for (SyncUnit *unit in self.selectedUnits) {
        [array addObject:[self dictionaryFromUnit:unit]];
    }

    [LocalStorage saveArray:array forKey:kSyncSelectedUnitsKey];
}

- (void)loadSelectedUnits {
    NSArray *stored = [LocalStorage loadArrayForKey:kSyncSelectedUnitsKey];
    if (!stored) return;

    [self.selectedUnits removeAllObjects];

    for (NSDictionary *dict in stored) {
        SyncUnit *unit = [self unitFromDictionary:dict];
        [self.selectedUnits addObject:unit];
    }

    self.selectedUnitCount = self.selectedUnits.count;
}

- (void)setupDummyData {
    // Dummy Units
    self.dummyUnits = [NSMutableArray array];
    for (int i = 1; i <= 12; i++) {
        SyncUnit *unit = [SyncUnit new];
        unit.planId = [NSString stringWithFormat:@"P%02d", i];
        unit.displayName = [NSString stringWithFormat:@"Unit %d-A", i];
        unit.projectId = [NSString stringWithFormat:@"PRJ%02d", i];
        unit.projectName = [NSString stringWithFormat:@"Project %d", i];
        unit.selected = i <= 3; // preselect first 3 units
        [self.dummyUnits addObject:unit];
    }

    // Dummy Projects
    self.dummyProjects = [NSMutableArray array];
    for (int i = 1; i <= 5; i++) {
        SyncProject *project = [SyncProject new];
        project.projectId = [NSString stringWithFormat:@"PRJ%02d", i];
        project.projectName = [NSString stringWithFormat:@"Project %d", i];

        NSMutableArray *units = [NSMutableArray array];
        for (int j = 1; j <= 3; j++) {
            SyncUnit *unit = [SyncUnit new];
            unit.planId = [NSString stringWithFormat:@"PRJ%02d-U%d", i, j];
            unit.displayName = [NSString stringWithFormat:@"Unit %d-%d", i, j];
            unit.projectId = project.projectId;
            unit.projectName = project.projectName;
            unit.selected = NO;
            [units addObject:unit];
        }
        project.units = units;
        [self.dummyProjects addObject:project];
    }
}

@end
