//  AppointmentViewMoreViewController.mm

#import "AppointmentViewMoreViewController.h"
#import "FSCalendar.h"
#import "DashboardAPIClient.h"
#import "AppointmentViewController.h"
#import "AppointmentDetailsViewController.h"

@interface ListingCell : UITableViewCell

@property (nonatomic, strong) UILabel *statusLabel;
@property (nonatomic, strong) UILabel *timeBadge;
@property (nonatomic, strong) UILabel *unitOwnerLabel;

@end

@implementation ListingCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (!self) return nil;

    // Status label (left top)
    self.statusLabel = [[UILabel alloc] init];
    self.statusLabel.font = [UIFont boldSystemFontOfSize:14];
    self.statusLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView addSubview:self.statusLabel];

    // Time badge (right top)
    self.timeBadge = [[UILabel alloc] init];
    self.timeBadge.font = [UIFont systemFontOfSize:12 weight:UIFontWeightSemibold];
    self.timeBadge.textAlignment = NSTextAlignmentCenter;
    self.timeBadge.layer.cornerRadius = 12;
    self.timeBadge.layer.masksToBounds = YES;
    self.timeBadge.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView addSubview:self.timeBadge];

    // Unit + Owner (full width bottom)
    self.unitOwnerLabel = [[UILabel alloc] init];
    self.unitOwnerLabel.font = [UIFont systemFontOfSize:13];
    self.unitOwnerLabel.textColor = UIColor.darkGrayColor;
    self.unitOwnerLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView addSubview:self.unitOwnerLabel];

    // AutoLayout constraints
    [NSLayoutConstraint activateConstraints:@[
        // top row left
        [self.statusLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:8],
        [self.statusLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],

        // top row right — time badge
        [self.timeBadge.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-16],
        [self.timeBadge.centerYAnchor constraintEqualToAnchor:self.statusLabel.centerYAnchor],
        [self.timeBadge.widthAnchor constraintEqualToConstant:70],
        [self.timeBadge.heightAnchor constraintEqualToConstant:24],

        // bottom row full width
        [self.unitOwnerLabel.topAnchor constraintEqualToAnchor:self.statusLabel.bottomAnchor constant:6],
        [self.unitOwnerLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:16],
        [self.unitOwnerLabel.trailingAnchor constraintEqualToAnchor:self.timeBadge.trailingAnchor],
        [self.unitOwnerLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-8]
    ]];

    return self;
}

@end


@interface AppointmentViewMoreViewController () <UITableViewDelegate, UITableViewDataSource, FSCalendarDelegate, FSCalendarDataSource>

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

@property (nonatomic, strong) UIView *filterBar;
@property (nonatomic, strong) UILabel *filterLabel;
@property (nonatomic, strong) UIButton *filterButton;

@property (nonatomic, strong) UIView *calendarContainer;
@property (nonatomic, strong) UIView *listingContainer;
@property (nonatomic, strong) UITableView *listingTable;

@property (nonatomic, strong) UIView *bottomButtonContainer;
@property (nonatomic, strong) UIButton *makeAppointmentButton;

@property (nonatomic, strong) UIView *filterOverlay;

@property (nonatomic, strong) UIActivityIndicatorView *loadingView;

@property (nonatomic, assign) BOOL showingCalendar;

@property (nonatomic, strong) NSArray *arrayAppointmentFull;
@property (nonatomic, strong) NSMutableArray *arrayListing;
@property (nonatomic, strong) NSMutableArray *arrayListingSection;
@property (nonatomic, strong) NSMutableDictionary *aryDotsByDate;

@property (nonatomic, copy) NSString *apptFilterType;
@property (nonatomic, copy) NSString *apptFilterTime;

@property (nonatomic, assign) BOOL blnLoading;
@property (nonatomic, assign) BOOL blnRefreshCalendar;

@property (nonatomic, strong) FSCalendar *calendar;

@end

@implementation AppointmentViewMoreViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
  
    self.arrayAppointmentFull = [NSMutableArray array];
    self.arrayListing = [NSMutableArray array];
    self.arrayListingSection = [NSMutableArray array];
    self.aryDotsByDate = [NSMutableDictionary dictionary];

    self.apptFilterType = @"All";
    self.apptFilterTime = @"Upcoming";

    self.showingCalendar = YES;

    [self setupTopBar];
    [self setupFilterBar];
    [self setupBottomButton];
    [self setupCalendarView];
    [self setupListingView];
    [self setupFilterOverlay];
    [self setupLoadingOverlay];
    [self fetchDashboardInfo];
}

#pragma mark - Top Bar
- (void)setupTopBar {
    self.topBar = [[UIView alloc] init];
    self.topBar.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0.55 alpha:1];
    self.topBar.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.topBar];

    self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
    self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
    [self.backButton setImage:[UIImage systemImageNamed:@"chevron.left"] forState:UIControlStateNormal];
    self.backButton.tintColor = UIColor.whiteColor;
    [self.topBar addSubview:self.backButton];
  
    self.titleLabel = [[UILabel alloc] init];
    self.titleLabel.text = @"Appointment";
    self.titleLabel.textColor = UIColor.whiteColor;
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
    self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.topBar addSubview:self.titleLabel];

    self.toggleTabButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.toggleTabButton setImage:[UIImage systemImageNamed:@"list.bullet"] forState:UIControlStateNormal];
    [self.toggleTabButton addTarget:self action:@selector(onToggleTab) forControlEvents:UIControlEventTouchUpInside];
    self.toggleTabButton.translatesAutoresizingMaskIntoConstraints = NO;
    self.toggleTabButton.tintColor = [UIColor whiteColor];
    [self.topBar addSubview:self.toggleTabButton];

    [NSLayoutConstraint activateConstraints:@[
        [self.topBar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
        [self.topBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.topBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.topBar.heightAnchor constraintEqualToConstant:56],

        [self.backButton.leadingAnchor constraintEqualToAnchor:self.topBar.leadingAnchor constant:12],
        [self.backButton.centerYAnchor constraintEqualToAnchor:self.topBar.centerYAnchor],
        [self.backButton.widthAnchor constraintEqualToConstant:48],
        [self.backButton.heightAnchor constraintEqualToConstant:48],

        [self.toggleTabButton.trailingAnchor constraintEqualToAnchor:self.topBar.trailingAnchor constant:-12],
        [self.toggleTabButton.centerYAnchor constraintEqualToAnchor:self.topBar.centerYAnchor],
        [self.toggleTabButton.widthAnchor constraintEqualToConstant:48],
        [self.toggleTabButton.heightAnchor constraintEqualToConstant:48],

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

#pragma mark - Filter Bar
- (void)setupFilterBar {
    self.filterBar = [[UIView alloc] init];
    self.filterBar.backgroundColor = [UIColor colorWithWhite:0.6 alpha:1];
    self.filterBar.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.filterBar];

    self.filterLabel = [[UILabel alloc] init];
    self.filterLabel.text = @"Filter by All (Upcoming)";
    self.filterLabel.textColor = UIColor.whiteColor;
    self.filterLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.filterBar addSubview:self.filterLabel];

    self.filterButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.filterButton setImage:[UIImage systemImageNamed:@"slider.horizontal.3"] forState:UIControlStateNormal];
    [self.filterButton addTarget:self action:@selector(onFilterButton) forControlEvents:UIControlEventTouchUpInside];
    self.filterButton.translatesAutoresizingMaskIntoConstraints = NO;
    self.filterButton.tintColor = [UIColor whiteColor];
    [self.filterBar addSubview:self.filterButton];

    [NSLayoutConstraint activateConstraints:@[
        [self.filterBar.topAnchor constraintEqualToAnchor:self.topBar.bottomAnchor],
        [self.filterBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.filterBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.filterBar.heightAnchor constraintEqualToConstant:48],

        [self.filterLabel.leadingAnchor constraintEqualToAnchor:self.filterBar.leadingAnchor constant:16],
        [self.filterLabel.centerYAnchor constraintEqualToAnchor:self.filterBar.centerYAnchor],

        [self.filterButton.trailingAnchor constraintEqualToAnchor:self.filterBar.trailingAnchor constant:-12],
        [self.filterButton.centerYAnchor constraintEqualToAnchor:self.filterBar.centerYAnchor],
        [self.filterButton.widthAnchor constraintEqualToConstant:36],
        [self.filterButton.heightAnchor constraintEqualToConstant:36]
    ]];
}

#pragma mark - Calendar
- (void)setupCalendarView {
    // 1️⃣ Calendar container
    self.calendarContainer = [[UIView alloc] init];
    self.calendarContainer.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.calendarContainer];

    // 2️⃣ FSCalendar
    self.calendar = [[FSCalendar alloc] init];
    self.calendar.dataSource = self;
    self.calendar.delegate = self;
    self.calendar.allowsMultipleSelection = NO;
    self.calendar.translatesAutoresizingMaskIntoConstraints = NO;
    [self.calendarContainer addSubview:self.calendar];

    // 3️⃣ Agenda table below calendar
    self.agendaTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    self.agendaTable.delegate = self;
    self.agendaTable.dataSource = self;
    self.agendaTable.translatesAutoresizingMaskIntoConstraints = NO;
    [self.calendarContainer addSubview:self.agendaTable];
    [self.agendaTable registerClass:[ListingCell class] forCellReuseIdentifier:@"ListingCell"];

    // 4️⃣ Constraints for calendarContainer
    [NSLayoutConstraint activateConstraints:@[
        [self.calendarContainer.topAnchor constraintEqualToAnchor:self.filterBar.bottomAnchor],
        [self.calendarContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.calendarContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.calendarContainer.bottomAnchor constraintEqualToAnchor:self.bottomButtonContainer.topAnchor]
    ]];

    // 5️⃣ Constraints for FSCalendar
    [NSLayoutConstraint activateConstraints:@[
        [self.calendar.topAnchor constraintEqualToAnchor:self.calendarContainer.topAnchor],
        [self.calendar.leadingAnchor constraintEqualToAnchor:self.calendarContainer.leadingAnchor],
        [self.calendar.trailingAnchor constraintEqualToAnchor:self.calendarContainer.trailingAnchor],
        [self.calendar.heightAnchor constraintEqualToConstant:320] // fixed calendar height
    ]];

    // 6️⃣ Constraints for agendaTable
    [NSLayoutConstraint activateConstraints:@[
        [self.agendaTable.topAnchor constraintEqualToAnchor:self.calendar.bottomAnchor],
        [self.agendaTable.leadingAnchor constraintEqualToAnchor:self.calendarContainer.leadingAnchor],
        [self.agendaTable.trailingAnchor constraintEqualToAnchor:self.calendarContainer.trailingAnchor],
        [self.agendaTable.bottomAnchor constraintEqualToAnchor:self.calendarContainer.bottomAnchor]
    ]];
}

- (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position {

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    df.dateFormat = @"dd MMM yyyy";
    NSString *selectedDate = [df stringFromDate:date];

    NSMutableArray *list = [NSMutableArray array];

    for (NSDictionary *item in self.arrayListing) {
        if ([item[@"start_date"] isEqualToString:selectedDate]) {
            [list addObject:item];
        }
    }

    self.agendaList = list;

    [self.agendaTable reloadData];
}

// If your FSCalendar supports eventColorsForDate:
- (NSArray<UIColor *> *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventColorsForDate:(NSDate *)date {
    NSDateFormatter *dfOut = [[NSDateFormatter alloc] init];
    dfOut.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    dfOut.dateFormat = @"yyyy-MM-dd";
    NSString *key = [dfOut stringFromDate:date];

    NSArray *dots = self.aryDotsByDate[key];
    if (!dots) return nil;
    NSMutableArray *colors = [NSMutableArray array];
    for (NSDictionary *d in dots) {
        UIColor *c = d[@"color"];
        if ([c isKindOfClass:[UIColor class]]) [colors addObject:c];
    }
    return colors;
}

- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date {
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    df.dateFormat = @"yyyy-MM-dd";
    NSString *key = [df stringFromDate:date];

    NSArray *events = self.aryDotsByDate[key];
    return events.count;   // number of dots to show
}

#pragma mark - Listing Container
- (void)setupListingView {
    // 1️⃣ Container for listing
    self.listingContainer = [[UIView alloc] init];
    self.listingContainer.backgroundColor = UIColor.whiteColor;
    self.listingContainer.translatesAutoresizingMaskIntoConstraints = NO;
    self.listingContainer.hidden = YES;
    [self.view addSubview:self.listingContainer];

    // 2️⃣ Listing table
    self.listingTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    self.listingTable.delegate = self;
    self.listingTable.dataSource = self;
    self.listingTable.translatesAutoresizingMaskIntoConstraints = NO;
    [self.listingContainer addSubview:self.listingTable];

    // ✅ Register cell class **before any dequeuing**
    [self.listingTable registerClass:[ListingCell class] forCellReuseIdentifier:@"ListingCell"];

    // 3️⃣ Container constraints
    [NSLayoutConstraint activateConstraints:@[
        [self.listingContainer.topAnchor constraintEqualToAnchor:self.filterBar.bottomAnchor],
        [self.listingContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.listingContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.listingContainer.bottomAnchor constraintEqualToAnchor:self.bottomButtonContainer.topAnchor]
    ]];

    // 4️⃣ Table fills container
    [NSLayoutConstraint activateConstraints:@[
        [self.listingTable.topAnchor constraintEqualToAnchor:self.listingContainer.topAnchor],
        [self.listingTable.leadingAnchor constraintEqualToAnchor:self.listingContainer.leadingAnchor],
        [self.listingTable.trailingAnchor constraintEqualToAnchor:self.listingContainer.trailingAnchor],
        [self.listingTable.bottomAnchor constraintEqualToAnchor:self.listingContainer.bottomAnchor]
    ]];

    // 5️⃣ Pull-to-refresh
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    [refresh addTarget:self action:@selector(onRefresh) forControlEvents:UIControlEventValueChanged];
    if (@available(iOS 10.0, *)) {
        self.listingTable.refreshControl = refresh;
    } else {
        [self.listingTable addSubview:refresh];
    }

    // 6️⃣ Ensure automatic row height (optional)
    self.listingTable.estimatedRowHeight = 60;
    self.listingTable.rowHeight = UITableViewAutomaticDimension;
}

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (tableView == self.agendaTable) return 1;
    return self.arrayListingSection.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView == self.agendaTable) return self.agendaList.count;
    NSDictionary *sec = self.arrayListingSection[section];
    return [sec[@"data"] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // ✅ Always dequeue after registering
    ListingCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListingCell" forIndexPath:indexPath];

    NSDictionary *item;
    if (tableView == self.agendaTable) {
        item = self.agendaList[indexPath.row];
    } else {
        NSDictionary *sec = self.arrayListingSection[indexPath.section];
        item = sec[@"data"][indexPath.row];
    }

    // Configure cell
    NSString *status = item[@"status"] ?: @"";
    NSString *apptType = item[@"appointment_type"] ?: @"";
    NSString *startTime = item[@"start_time"] ?: @"";

    cell.statusLabel.text = [status isEqualToString:@"Cancelled"] ? status : apptType;

    cell.timeBadge.text = startTime;
    cell.timeBadge.backgroundColor = [apptType isEqualToString:@"Handover"]
        ? [self colorFromHex:@"#047C74"]
        : [self colorFromHex:@"#C84132"];
    cell.timeBadge.textColor = UIColor.whiteColor;

    NSArray *primary = item[@"primary_buyer"];
    NSArray *joint = item[@"joint_buyer"];
    NSString *owner = (primary.count > 0) ? primary[0][@"name"]
                  : (joint.count > 0 ? joint[0][@"name"] : @"");

    cell.unitOwnerLabel.text = [NSString stringWithFormat:@"%@ (%@)", item[@"unit_no"], owner];

    return cell;
}

#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 60; // fixed height
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return tableView == self.agendaTable ? 0.1 : 30;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 0.1;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (tableView == self.agendaTable) return [UIView new];

    NSDictionary *sec = self.arrayListingSection[section];
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(16, 0, tableView.bounds.size.width - 32, 30)];
    lbl.text = sec[@"title"];
    lbl.font = [UIFont boldSystemFontOfSize:14];
    lbl.textColor = UIColor.darkGrayColor;

    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
    [v addSubview:lbl];
    return v;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *item = tableView == self.agendaTable ? self.agendaList[indexPath.row]
                                                        : self.arrayListingSection[indexPath.section][@"data"][indexPath.row];
    [self clickListingItemWithItem:item];
}

- (void)clickListingItemWithItem:(NSDictionary *)item {
    AppointmentDetailsViewController *vc = [[AppointmentDetailsViewController alloc] initWithNibName:nil bundle:nil];
    vc.appointmentData = item;
    vc.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:vc animated:YES completion:nil];
}

- (void)onRefresh {
        [self fetchDashboardInfo];
}

#pragma mark - Bottom Button
- (void)setupBottomButton {
    self.bottomButtonContainer = [[UIView alloc] init];
    self.bottomButtonContainer.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0.55 alpha:1];
    self.bottomButtonContainer.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.bottomButtonContainer];
    
    self.makeAppointmentButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.makeAppointmentButton setTitle:@"Make Appointment" forState:UIControlStateNormal];
    [self.makeAppointmentButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    self.makeAppointmentButton.translatesAutoresizingMaskIntoConstraints = NO;
    [self.makeAppointmentButton addTarget:self action:@selector(onMakeAppointment) forControlEvents:UIControlEventTouchUpInside];
    [self.bottomButtonContainer addSubview:self.makeAppointmentButton];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.bottomButtonContainer.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
        [self.bottomButtonContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.bottomButtonContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.bottomButtonContainer.heightAnchor constraintEqualToConstant:56],
        
        [self.makeAppointmentButton.topAnchor constraintEqualToAnchor:self.bottomButtonContainer.topAnchor],
        [self.makeAppointmentButton.bottomAnchor constraintEqualToAnchor:self.bottomButtonContainer.bottomAnchor],
        [self.makeAppointmentButton.leadingAnchor constraintEqualToAnchor:self.bottomButtonContainer.leadingAnchor],
        [self.makeAppointmentButton.trailingAnchor constraintEqualToAnchor:self.bottomButtonContainer.trailingAnchor]
    ]];
}


#pragma mark - Filter Overlay
- (void)setupFilterOverlay {
    self.filterOverlay = [[UIView alloc] initWithFrame:self.view.bounds];
    self.filterOverlay.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
    self.filterOverlay.hidden = YES;

    CGFloat y = 120;
    NSArray *typeTitles = @[@"All", @"Handover", @"Joint Inspection", @"Rectification"];
    for (int i=0; i<typeTitles.count; i++) {
        UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
        b.frame = CGRectMake(0, y + i*50, self.view.bounds.size.width, 50);
        [b setTitle:typeTitles[i] forState:UIControlStateNormal];
        [b addTarget:self action:@selector(onFilterTypeTap:) forControlEvents:UIControlEventTouchUpInside];
        b.tag = i;
        [self.filterOverlay addSubview:b];

        UIImageView *radio = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - 40, y + i*50 + 12, 24, 24)];
        radio.tag = 100 + i;
        radio.image = [self.apptFilterType isEqualToString:typeTitles[i]] ? [UIImage imageNamed:@"radio_check"] : [UIImage imageNamed:@"radio_uncheck"];
        [self.filterOverlay addSubview:radio];
    }

    // Time filter section
    CGFloat timeStartY = y + typeTitles.count * 50 + 20;

    NSArray *timeTitles = @[@"Upcoming", @"History"];
    for (int i = 0; i < timeTitles.count; i++) {
        UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
        b.frame = CGRectMake(0, timeStartY + i * 50, self.view.bounds.size.width, 50);
        [b setTitle:timeTitles[i] forState:UIControlStateNormal];
        [b addTarget:self action:@selector(onFilterTimeTap:) forControlEvents:UIControlEventTouchUpInside];
        b.tag = 200 + i;
        [self.filterOverlay addSubview:b];

        UIImageView *radio = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - 40,
                                                                           timeStartY + i * 50 + 12,
                                                                           24, 24)];
        radio.tag = 300 + i;
        radio.image = [self.apptFilterTime isEqualToString:timeTitles[i]]
                      ? [UIImage imageNamed:@"radio_check"]
                      : [UIImage imageNamed:@"radio_uncheck"];
        [self.filterOverlay addSubview:radio];
    }
  
    // Add done/back handling (tap background to close)
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideFilterOverlay)];
    [self.filterOverlay addGestureRecognizer:tap];

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

- (void)onFilterTypeTap:(UIButton *)sender {
  [self refreshFilterOverlay];
    NSArray *typeTitles = @[@"All", @"Handover", @"Joint Inspection", @"Rectification"];
    NSString *selected = typeTitles[sender.tag];
    self.apptFilterType = selected;
    self.filterOverlay.hidden = YES;
    self.blnLoading = YES;
    [self.loadingView startAnimating];
    // process
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self processAppointmentData:self.arrayAppointmentFull];
        [self.loadingView stopAnimating];
    });
}

- (void)onFilterTimeTap:(UIButton *)sender {
  [self refreshFilterOverlay];
    NSArray *timeTitles = @[@"Upcoming", @"History"];
    NSString *selected = timeTitles[sender.tag - 200];
    self.apptFilterTime = selected;

    self.filterOverlay.hidden = YES;
    self.blnLoading = YES;
    [self.loadingView startAnimating];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)),
                   dispatch_get_main_queue(), ^{
        [self processAppointmentData:self.arrayAppointmentFull];
        [self.loadingView stopAnimating];
    });
}

- (void)hideFilterOverlay {
    self.filterOverlay.hidden = YES;
}

- (void)refreshFilterOverlay {
    NSArray *typeTitles = @[@"All", @"Handover", @"Joint Inspection", @"Rectification"];
    for (int i = 0; i < typeTitles.count; i++) {
        UIImageView *radio = [self.filterOverlay viewWithTag:100 + i];
        radio.image = [self.apptFilterType isEqualToString:typeTitles[i]]
                      ? [UIImage imageNamed:@"radio_check"]
                      : [UIImage imageNamed:@"radio_uncheck"];
    }

    NSArray *timeTitles = @[@"Upcoming", @"History"];
    for (int i = 0; i < timeTitles.count; i++) {
        UIImageView *radio = [self.filterOverlay viewWithTag:300 + i];
        radio.image = [self.apptFilterTime isEqualToString:timeTitles[i]]
                      ? [UIImage imageNamed:@"radio_check"]
                      : [UIImage imageNamed:@"radio_uncheck"];
    }
}

#pragma mark - Loading Overlay
- (void)setupLoadingOverlay {
    self.loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
    self.loadingView.center = self.view.center;
    self.loadingView.hidesWhenStopped = YES;
    [self.view addSubview:self.loadingView];
}

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

- (void)onToggleTab {
    if (self.blnLoading) return;
    self.blnLoading = YES;
    [self.loadingView startAnimating];

    [UIView animateWithDuration:0.3 animations:^{
        self.showingCalendar = !self.showingCalendar;
        self.calendarContainer.alpha = self.showingCalendar ? 1 : 0;
        self.listingContainer.alpha = self.showingCalendar ? 0 : 1;
    } completion:^(BOOL finished) {
        self.calendarContainer.hidden = !self.showingCalendar;
        self.listingContainer.hidden = self.showingCalendar;

        NSString *imgName = self.showingCalendar ? @"listing_icon_white" : @"calendar_icon_white";
        [self.toggleTabButton setImage:[UIImage imageNamed:imgName] forState:UIControlStateNormal];

        self.blnLoading = NO;
        [self.loadingView stopAnimating];
    }];
}

- (void)onFilterButton {
    self.filterOverlay.hidden = !self.filterOverlay.hidden;
}

- (void)onMakeAppointment {
    AppointmentViewController *vc = [[AppointmentViewController alloc] initWithNibName:nil bundle:nil];
    vc.projectCode = @"PTD197656";
    vc.projectName = @"Ara E`Residence Dev";
    vc.projectId = @"8";
    vc.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:vc animated:YES completion:nil];
}

#pragma mark - api
- (void)fetchDashboardInfo {
        [self.loadingView startAnimating];

      [DashboardAPIClient fetchDashboardInfo:^(NSDictionary *data, NSError *error) {
        
        [self.loadingView stopAnimating];
        
        if (error) {
          NSLog(@"❌ Failed to load dashboard info: %@", error);
          [self showError:@"Unable to load appointment data."];
          return;
        }
        
        if (![data isKindOfClass:[NSDictionary class]]) {
          [self showError:@"Invalid response from server."];
          return;
        }
        
        NSLog(@"✅ Dashboard Info Loaded!");
        
        // 🔥 Extract appointment array based on your API response shape
        NSArray *appointments = data[@"Data"][@"appointment"];
        if (![appointments isKindOfClass:[NSArray class]]) {
          appointments = @[];
        }

        // Save it for later use
        self.arrayAppointmentFull = appointments;
        
        NSLog(@"📦 Received Appointment Data: %@", self.arrayAppointmentFull);
        NSString *text = [NSString stringWithFormat:@"%@", self.arrayAppointmentFull];
        NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        NSString *filePath = [docsPath stringByAppendingPathComponent:@"appointFull.txt"];
        
        // Convert issueData to a readable string
        NSString *plainText = [NSString stringWithFormat:@"%@", self.arrayAppointmentFull];

        // Write as plain UTF-8 text
        [plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];

        // Log the path so you can find it
        NSLog(@"📁 appointData saved as plain text to: %@", filePath);

        // 🔧 Process filters + convert to sectionized data + refresh UI
        [self processAppointmentData:self.arrayAppointmentFull];
    }];
}

- (void)endRefreshWithNoData {
    self.blnRefreshCalendar = NO;
    [self.listingTable reloadData];
}

- (void)processAppointmentData:(NSArray *)data {
    if (!data) {
        [self.arrayListing removeAllObjects];
        [self.arrayListingSection removeAllObjects];
        [self.listingTable reloadData];
        return;
    }

    // 1. Filter by type and time
    NSMutableArray *filtered = [NSMutableArray array];
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    df.dateFormat = @"dd MMM yyyy hh:mm a"; // matches RN format 'DD MMM YYYY hh:mm a'

    for (NSDictionary *item in data) {
        NSString *apptType = item[@"appointment_type"] ?: @"";
        NSString *startDate = item[@"start_date"] ?: @""; // 'DD MMM YYYY'
        NSString *startTime = item[@"start_time"] ?: @""; // 'hh:mm a'

        // combine and parse
        NSString *combined = [NSString stringWithFormat:@"%@ %@", startDate, startTime];
        NSDate *startDateTime = [df dateFromString:combined];
        if (!startDateTime) continue;

        // determine upcoming vs history
        BOOL isHistory = [startDateTime timeIntervalSinceNow] < 0;

        // time filter
        BOOL timePass = YES;
        if ([self.apptFilterTime isEqualToString:@"History"]) {
            timePass = isHistory;
        } else if ([self.apptFilterTime isEqualToString:@"Upcoming"]) {
            timePass = !isHistory;
        }

        // type filter
        BOOL typePass = YES;
        if (![self.apptFilterType isEqualToString:@"All"]) {
            typePass = [apptType isEqualToString:self.apptFilterType];
        }

        if (timePass && typePass) {
            [filtered addObject:item];
        }
    }

    // 2. Sort
    [filtered sortUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b) {
        NSString *aCombined = [NSString stringWithFormat:@"%@ %@", a[@"start_date"], a[@"start_time"]];
        NSString *bCombined = [NSString stringWithFormat:@"%@ %@", b[@"start_date"], b[@"start_time"]];
        NSDate *aDate = [df dateFromString:aCombined];
        NSDate *bDate = [df dateFromString:bCombined];
        if (!aDate || !bDate) return NSOrderedSame;
        if ([self.apptFilterTime isEqualToString:@"Upcoming"]) {
            return [aDate compare:bDate];
        } else {
            return [bDate compare:aDate];
        }
    }];

    // 3. Build sections grouped by start_date
    [self.arrayListing removeAllObjects];
    [self.arrayListing addObjectsFromArray:filtered];

    [self.arrayListingSection removeAllObjects];
    NSMutableDictionary *sectionsDict = [NSMutableDictionary dictionary];
    for (NSDictionary *item in filtered) {
        NSString *dateKey = item[@"start_date"] ?: @"";
        if (!dateKey) continue;
        if (!sectionsDict[dateKey]) sectionsDict[dateKey] = [NSMutableArray array];
        [sectionsDict[dateKey] addObject:item];
    }
    // convert to array preserving order of filtered array
    NSMutableSet *seenDates = [NSMutableSet set];
    for (NSDictionary *item in filtered) {
        NSString *dateKey = item[@"start_date"];
        if (![seenDates containsObject:dateKey]) {
            [seenDates addObject:dateKey];
            NSArray *itemsForDate = sectionsDict[dateKey];
            NSDictionary *section = @{@"title": dateKey, @"data": itemsForDate ?: @[]};
            [self.arrayListingSection addObject:section];
        }
    }

    // 4. Build dots map (date -> array of {type,color})
    [self.aryDotsByDate removeAllObjects];
    for (NSDictionary *item in self.arrayListing) {
        NSString *strConvertDate = item[@"start_date"]; // 'DD MMM YYYY'
        // convert to yyyy-MM-dd key
        NSDateFormatter *dfIn = [[NSDateFormatter alloc] init];
        dfIn.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
        dfIn.dateFormat = @"dd MMM yyyy";
        NSDate *d = [dfIn dateFromString:strConvertDate];
        NSDateFormatter *dfOut = [[NSDateFormatter alloc] init];
        dfOut.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
        dfOut.dateFormat = @"yyyy-MM-dd";
        NSString *key = [dfOut stringFromDate:d] ?: strConvertDate;

        NSString *type = item[@"appointment_type"] ?: @"";
        UIColor *color = [type isEqualToString:@"Handover"] ? [self colorFromHex:@"#047C74"] : [self colorFromHex:@"#C84132"];

        NSMutableArray *dots = self.aryDotsByDate[key];
        if (!dots) {
            dots = [NSMutableArray array];
            self.aryDotsByDate[key] = dots;
        }
        [dots addObject:@{@"type": type, @"color": color}];
    }

    // 5. refresh table + calendar
    [self.listingTable reloadData];
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];

    NSDateFormatter *dfIn = [[NSDateFormatter alloc] init];
    dfIn.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    dfIn.dateFormat = @"dd MMM yyyy";

    NSDateFormatter *dfOut = [[NSDateFormatter alloc] init];
    dfOut.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    dfOut.dateFormat = @"yyyy-MM-dd";

    for (NSDictionary *item in self.arrayListing) {

        NSString *startDateStr = item[@"start_date"]; // "27 Nov 2025"
        NSDate *d = [dfIn dateFromString:startDateStr];
        if (!d) continue;

        NSString *key = [dfOut stringFromDate:d];

        // Status color logic
        NSString *apptType = item[@"appointment_type"];
        UIColor *c = [apptType isEqualToString:@"Handover"]
            ? [self colorFromHex:@"#047C74"]
            : [self colorFromHex:@"#C84132"];

        if (!dict[key]) dict[key] = [NSMutableArray array];
        [dict[key] addObject:@{ @"color": c }];
    }

    self.aryDotsByDate = dict;
    [self.calendar reloadData];

    self.blnRefreshCalendar = YES;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.blnRefreshCalendar = NO;
    });
  
    self.filterLabel.text = [NSString stringWithFormat:@"Filter by %@ (%@)",
                              self.apptFilterType,
                              self.apptFilterTime];
  
    // Auto-select today or first date that has appointments
    NSDateFormatter *dfToday = [[NSDateFormatter alloc] init];
    dfToday.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    dfToday.dateFormat = @"dd MMM yyyy";
    NSString *todayString = [dfToday stringFromDate:[NSDate date]];

    df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    df.dateFormat = @"dd MMM yyyy";

    NSMutableArray *todayList = [NSMutableArray array];

    for (NSDictionary *item in self.arrayListing) {
        if ([item[@"start_date"] isEqualToString:todayString]) {
            [todayList addObject:item];
        }
    }
    
    if (todayList.count > 0) {
        [self.calendar selectDate:[NSDate date] scrollToDate:YES];
        self.agendaList = todayList;
    } else if (self.arrayListing.count > 0) {
        NSDictionary *firstItem = self.arrayListing[0];
        NSDate *firstDate = [df dateFromString:firstItem[@"start_date"]];
        if (firstDate) {
            [self.calendar selectDate:firstDate scrollToDate:YES];
            // populate agendaList for firstDate
            NSMutableArray *firstDateList = [NSMutableArray array];
            for (NSDictionary *item in self.arrayListing) {
                if ([item[@"start_date"] isEqualToString:firstItem[@"start_date"]]) {
                    [firstDateList addObject:item];
                }
            }
            self.agendaList = firstDateList;
        }
    }
    [self.agendaTable reloadData];
}

- (UIColor *)colorFromHex:(NSString *)hex {
    unsigned rgbValue = 0;
    NSScanner *scanner = [NSScanner scannerWithString:hex];
    [scanner setScanLocation:1]; // bypass '#'
    [scanner scanHexInt:&rgbValue];
    return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
                           green:((rgbValue & 0xFF00) >> 8)/255.0
                            blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
}

- (void)showError:(NSString *)message {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}

@end
