//
//  KBKeyboardView.m
//  CustomKeyboard
//

#import "KBKeyboardView.h"
#import "KBKeyButton.h"
#import "KBKey.h"
#import "KBResponderUtils.h" // 封装的响应链工具
#import "KBSkinManager.h"

@interface KBKeyboardView ()
@property (nonatomic, strong) UIView *row1;
@property (nonatomic, strong) UIView *row2;
@property (nonatomic, strong) UIView *row3;
@property (nonatomic, strong) UIView *row4;
@property (nonatomic, strong) NSArray<NSArray<KBKey *> *> *keysForRows;
// 长按退格的一次次删除控制标记（不使用 NSTimer，仅用 GCD 递归调度）
@property (nonatomic, assign) BOOL backspaceHoldActive;
@end

@implementation KBKeyboardView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [KBSkinManager shared].current.keyboardBackground;
        _layoutStyle = KBKeyboardLayoutStyleLetters;
        // 默认小写：与需求一致，初始不开启 Shift
        _shiftOn = NO;
        _symbolsMoreOn = NO; // 数字面板默认第一页（123）
        [self buildBase];
        [self reloadKeys];
    }
    return self;
}

// 当切换大布局（字母/数字）时，重置数字二级页状态
- (void)setLayoutStyle:(KBKeyboardLayoutStyle)layoutStyle {
    _layoutStyle = layoutStyle;
    if (_layoutStyle != KBKeyboardLayoutStyleNumbers) {
        _symbolsMoreOn = NO;
    }
}

- (void)buildBase {
    [self addSubview:self.row1];
    [self addSubview:self.row2];
    [self addSubview:self.row3];
    [self addSubview:self.row4];

    CGFloat vSpacing = 8;
    [self.row1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mas_top).offset(8);
        make.left.right.equalTo(self);
        make.height.mas_equalTo(44);
    }];
    [self.row2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.row1.mas_bottom).offset(vSpacing);
        make.left.right.equalTo(self);
        make.height.equalTo(self.row1);
    }];
    [self.row3 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.row2.mas_bottom).offset(vSpacing);
        make.left.right.equalTo(self);
        make.height.equalTo(self.row1);
    }];
    [self.row4 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.row3.mas_bottom).offset(vSpacing);
        make.left.right.equalTo(self);
        make.height.equalTo(self.row1);
        make.bottom.equalTo(self.mas_bottom).offset(-6);
    }];
}

- (void)reloadKeys {
    // 移除旧按钮
    for (UIView *row in @[self.row1, self.row2, self.row3, self.row4]) {
        [row.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    }

    self.keysForRows = [self buildKeysForCurrentLayout];
    [self buildRow:self.row1 withKeys:self.keysForRows[0]];
    // 第二行：字母布局时通过左右等宽占位让整行居中
    CGFloat row2Spacer = (self.layoutStyle == KBKeyboardLayoutStyleLetters) ? 0.5 : 0.0;
    [self buildRow:self.row2 withKeys:self.keysForRows[1] edgeSpacerMultiplier:row2Spacer];
    [self buildRow:self.row3 withKeys:self.keysForRows[2]];
    [self buildRow:self.row4 withKeys:self.keysForRows[3]];
}

- (NSArray<NSArray<KBKey *> *> *)buildKeysForCurrentLayout {
    if (self.layoutStyle == KBKeyboardLayoutStyleNumbers) {
        // 数字/符号布局：3 行主键 + 底部控制行
        NSArray *r1 = nil;
        NSArray *r2 = nil;
        NSArray *r3 = nil;

        if (!self.symbolsMoreOn) {
            // 数字第一页（123）
            r1 = @[ [KBKey keyWithTitle:@"1" output:@"1"], [KBKey keyWithTitle:@"2" output:@"2"], [KBKey keyWithTitle:@"3" output:@"3"],
                    [KBKey keyWithTitle:@"4" output:@"4"], [KBKey keyWithTitle:@"5" output:@"5"], [KBKey keyWithTitle:@"6" output:@"6"],
                    [KBKey keyWithTitle:@"7" output:@"7"], [KBKey keyWithTitle:@"8" output:@"8"], [KBKey keyWithTitle:@"9" output:@"9"], [KBKey keyWithTitle:@"0" output:@"0"] ];
            r2 = @[ [KBKey keyWithTitle:@"-" output:@"-"], [KBKey keyWithTitle:@"/" output:@"/"], [KBKey keyWithTitle:@":" output:@":"],
                    [KBKey keyWithTitle:@";" output:@";"], [KBKey keyWithTitle:@"(" output:@"("], [KBKey keyWithTitle:@")" output:@")"],
                    [KBKey keyWithTitle:@"$" output:@"$"], [KBKey keyWithTitle:@"&" output:@"&"], [KBKey keyWithTitle:@"@" output:@"@"], [KBKey keyWithTitle:@"\"" output:@"\""] ];
            r3 = @[ [KBKey keyWithTitle:@"#+=" type:KBKeyTypeSymbolsToggle],
                    [KBKey keyWithTitle:@"," output:@","], [KBKey keyWithTitle:@"." output:@"."], [KBKey keyWithTitle:@"?" output:@"?"],
                    [KBKey keyWithTitle:@"!" output:@"!"], [KBKey keyWithTitle:@"'" output:@"'"],
                    [KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace] ];
        } else {
            // 数字第二页（#+=）：前两行替换为更多符号，左下角按钮文案改为“123”
            r1 = @[ [KBKey keyWithTitle:@"[" output:@"["], [KBKey keyWithTitle:@"]" output:@"]"], [KBKey keyWithTitle:@"{" output:@"{"],
                    [KBKey keyWithTitle:@"}" output:@"}"], [KBKey keyWithTitle:@"#" output:@"#"], [KBKey keyWithTitle:@"%" output:@"%"],
                    [KBKey keyWithTitle:@"^" output:@"^"], [KBKey keyWithTitle:@"*" output:@"*"], [KBKey keyWithTitle:@"+" output:@"+"],
                    [KBKey keyWithTitle:@"=" output:@"="] ];
            r2 = @[ [KBKey keyWithTitle:@"_" output:@"_"], [KBKey keyWithTitle:@"\\" output:@"\\"], [KBKey keyWithTitle:@"|" output:@"|"],
                    [KBKey keyWithTitle:@"~" output:@"~"], [KBKey keyWithTitle:@"<" output:@"<"], [KBKey keyWithTitle:@">" output:@">"],
                    [KBKey keyWithTitle:@"$" output:@"$"], [KBKey keyWithTitle:@"€" output:@"€"], [KBKey keyWithTitle:@"£" output:@"£"],
                    [KBKey keyWithTitle:@"•" output:@"•"] ];
            r3 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeSymbolsToggle],
                    [KBKey keyWithTitle:@"," output:@","], [KBKey keyWithTitle:@"." output:@"."], [KBKey keyWithTitle:@"?" output:@"?"],
                    [KBKey keyWithTitle:@"!" output:@"!"], [KBKey keyWithTitle:@"'" output:@"'"],
                    [KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace] ];
        }

        NSArray *r4 = @[ [KBKey keyWithTitle:@"abc" type:KBKeyTypeModeChange],
                         [KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
                         [KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
                         [KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ];

        return @[r1, r2, r3, r4];
    }

    // 字母布局（QWERTY）
    NSArray *r1 = @[ @"Q", @"W", @"E", @"R", @"T", @"Y", @"U", @"I", @"O", @"P" ];
    NSArray *r2 = @[ @"A", @"S", @"D", @"F", @"G", @"H", @"J", @"K", @"L" ];
    NSArray *r3chars = @[ @"Z", @"X", @"C", @"V", @"B", @"N", @"M" ];

    NSMutableArray *row1 = [NSMutableArray arrayWithCapacity:r1.count];
    // 字母键标题与输出同时随 Shift 切换大小写，界面与输入保持一致
    for (NSString *s in r1) {
        NSString *shown = self.shiftOn ? s : s.lowercaseString;
        [row1 addObject:[KBKey keyWithTitle:shown output:shown]];
    }

    NSMutableArray *row2 = [NSMutableArray arrayWithCapacity:r2.count];
    for (NSString *s in r2) {
        NSString *shown = self.shiftOn ? s : s.lowercaseString;
        [row2 addObject:[KBKey keyWithTitle:shown output:shown]];
    }

    NSMutableArray *row3 = [NSMutableArray array];
    [row3 addObject:[KBKey keyWithTitle:@"⇧" type:KBKeyTypeShift]];
    for (NSString *s in r3chars) {
        NSString *shown = self.shiftOn ? s : s.lowercaseString;
        [row3 addObject:[KBKey keyWithTitle:shown output:shown]];
    }
    [row3 addObject:[KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace]];

    NSArray *row4 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeModeChange],
                       [KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
                       [KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
                       [KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ];

    return @[row1.copy, row2.copy, row3.copy, row4];
}

- (void)buildRow:(UIView *)row withKeys:(NSArray<KBKey *> *)keys {
    [self buildRow:row withKeys:keys edgeSpacerMultiplier:0.0];
}

- (void)buildRow:(UIView *)row withKeys:(NSArray<KBKey *> *)keys edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier {
    CGFloat hInset = 6;   // 行左右内边距
    CGFloat spacing = 6;  // 键与键之间的间距
    UIView *previous = nil;
    UIView *leftSpacer = nil;
    UIView *rightSpacer = nil;
    if (edgeSpacerMultiplier > 0.0) {
        leftSpacer = [UIView new];
        rightSpacer = [UIView new];
        leftSpacer.backgroundColor = [UIColor clearColor];
        rightSpacer.backgroundColor = [UIColor clearColor];
        [row addSubview:leftSpacer];
        [row addSubview:rightSpacer];
        [leftSpacer mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(row.mas_left).offset(hInset);
            make.centerY.equalTo(row);
            make.height.mas_equalTo(1);
        }];
        [rightSpacer mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(row.mas_right).offset(-hInset);
            make.centerY.equalTo(row);
            make.height.mas_equalTo(1);
        }];
    }
    for (NSInteger i = 0; i < keys.count; i++) {
        KBKey *key = keys[i];
        KBKeyButton *btn = [[KBKeyButton alloc] init];
        btn.key = key;
        [btn setTitle:key.title forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(onKeyTapped:) forControlEvents:UIControlEventTouchUpInside];
        [row addSubview:btn];

        // ⌫ 长按：开始连续逐个删除（无需 NSTimer）。使用 UILongPressGestureRecognizer 识别长按，
        // 在开始态触发递归的轻量调度，每次删除 1 个字符，直到松手或无内容。
        if (key.type == KBKeyTypeBackspace) {
            UILongPressGestureRecognizer *lp = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onBackspaceLongPress:)];
            // 稍短的判定时间，提升响应（默认约 0.5s）。
            lp.minimumPressDuration = 0.35;
            lp.cancelsTouchesInView = YES; // 被识别为长按时，取消普通点击
            [btn addGestureRecognizer:lp];
        }

        // Shift 按钮选中态随大小写状态变化
        if (key.type == KBKeyTypeShift) {
            btn.selected = self.shiftOn;
        }

        [btn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.bottom.equalTo(row);
            if (previous) {
                make.left.equalTo(previous.mas_right).offset(spacing);
            } else {
                if (leftSpacer) {
                    make.left.equalTo(leftSpacer.mas_right).offset(spacing);
                } else {
                    make.left.equalTo(row.mas_left).offset(hInset);
                }
            }
        }];

        // 宽度规则：字符键等宽；特殊键按倍数放大
        if (key.type == KBKeyTypeCharacter) {
            if (previous && previous != nil) {
                if (((KBKeyButton *)previous).key.type == KBKeyTypeCharacter) {
                    [btn mas_makeConstraints:^(MASConstraintMaker *make) {
                        make.width.equalTo(previous);
                    }];
                }
            }
        } else {
            // special keys: give 1.5x of a character key by deferring constraint equalities after loop
        }

        previous = btn;
    }
    // 右侧使用内边距或右占位
    [previous mas_makeConstraints:^(MASConstraintMaker *make) {
        if (rightSpacer) {
            make.right.equalTo(rightSpacer.mas_left).offset(-spacing);
        } else {
            make.right.equalTo(row.mas_right).offset(-hInset);
        }
    }];

    // 第二遍：以首个字符键为基准，统一设置特殊键宽度倍数
    KBKeyButton *firstChar = nil;
    for (KBKeyButton *b in row.subviews) {
        if ([b isKindOfClass:[KBKeyButton class]] && b.key.type == KBKeyTypeCharacter) { firstChar = b; break; }
    }
    // 若该行没有字符键（例如底部控制行），则使用行内第一个按钮作为基准宽度
    if (!firstChar) {
        for (KBKeyButton *b in row.subviews) { if ([b isKindOfClass:[KBKeyButton class]]) { firstChar = b; break; } }
    }
    if (firstChar) {
        for (KBKeyButton *b in row.subviews) {
            if (![b isKindOfClass:[KBKeyButton class]]) continue;
            // 当本行没有字符键时，firstChar 可能是一个“特殊键”，
            // 避免对基准按钮自身添加 self == self * k 的无效约束
            if (b == firstChar) continue;
            if (b.key.type == KBKeyTypeCharacter) continue;
            CGFloat multiplier = 1.5;
            if (b.key.type == KBKeyTypeSpace) multiplier = 4.0;
            if (b.key.type == KBKeyTypeReturn) multiplier = 1.8;
            if (b.key.type == KBKeyTypeModeChange || b.key.type == KBKeyTypeGlobe || b.key.type == KBKeyTypeShift || b.key.type == KBKeyTypeBackspace) {
                multiplier = 1.5;
            }
            [b mas_makeConstraints:^(MASConstraintMaker *make) {
                make.width.equalTo(firstChar).multipliedBy(multiplier);
            }];
        }
        // 如果有左右占位，则把占位宽度设置为字符键宽度的一定倍数，以实现整体居中
        if (leftSpacer && rightSpacer) {
            [leftSpacer mas_makeConstraints:^(MASConstraintMaker *make) {
                make.width.equalTo(firstChar).multipliedBy(edgeSpacerMultiplier);
            }];
            [rightSpacer mas_makeConstraints:^(MASConstraintMaker *make) {
                make.width.equalTo(firstChar).multipliedBy(edgeSpacerMultiplier);
            }];
        }
    }
}

#pragma mark - Actions

- (void)onKeyTapped:(KBKeyButton *)sender {
    KBKey *key = sender.key;
    if (key.type == KBKeyTypeShift) {
        self.shiftOn = !self.shiftOn;
        [self reloadKeys];
        return;
    }
    if (key.type == KBKeyTypeSymbolsToggle) {
        // 在数字布局内切换 123 <-> #+=
        self.symbolsMoreOn = !self.symbolsMoreOn;
        [self reloadKeys];
        return;
    }
    if ([self.delegate respondsToSelector:@selector(keyboardView:didTapKey:)]) {
        [self.delegate keyboardView:self didTapKey:key];
    }
}

// 长按退格：按住时以小间隔逐个删除；松手停止。（不使用 NSTimer/DisplayLink）
- (void)onBackspaceLongPress:(UILongPressGestureRecognizer *)gr {
    switch (gr.state) {
        case UIGestureRecognizerStateBegan: {
            self.backspaceHoldActive = YES;
            [self kb_backspaceStep];
        } break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateFailed: {
            self.backspaceHoldActive = NO;
        } break;
        default: break;
    }
}

#pragma mark - Helpers

// 单步删除并在需要时安排下一次，直到松手或无内容
- (void)kb_backspaceStep {
    if (!self.backspaceHoldActive) { return; }
    UIInputViewController *ivc = KBFindInputViewController(self);
    if (!ivc) { self.backspaceHoldActive = NO; return; }
    id<UITextDocumentProxy> proxy = ivc.textDocumentProxy;
    NSString *before = proxy.documentContextBeforeInput ?: @"";
    if (before.length <= 0) { self.backspaceHoldActive = NO; return; }
    [proxy deleteBackward]; // 每次仅删 1 个

    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.06 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        __strong typeof(weakSelf) selfStrong = weakSelf;
        [selfStrong kb_backspaceStep];
    });
}

#pragma mark - Lazy

- (UIView *)row1 { if (!_row1) _row1 = [UIView new]; return _row1; }
- (UIView *)row2 { if (!_row2) _row2 = [UIView new]; return _row2; }
- (UIView *)row3 { if (!_row3) _row3 = [UIView new]; return _row3; }
- (UIView *)row4 { if (!_row4) _row4 = [UIView new]; return _row4; }

@end
