//
//  YMNextGrowingTextView.m
//  PCDBank
//
//  Created by Gusont on 2021/8/20.
//  Copyright © 2021 SLAiELTS. All rights reserved.
//

#import "YMNextGrowingTextView.h"

@interface YMNextGrowingTextView()

@property (nonatomic, assign) CGFloat maxHeight;
@property (nonatomic, assign) CGFloat minHeight;
@property (nonatomic, assign) CGRect previousFrame;

@end

@implementation YMNextGrowingTextView

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.textView = [[YMNextGrowingInternalTextView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        self.previousFrame = frame;
        [self setup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.textView = [[YMNextGrowingInternalTextView alloc] initWithFrame:CGRectZero];
        self.previousFrame = self.frame;
        self.textView.frame = self.bounds;
        [self setup];
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    if (_previousFrame.size.width != self.bounds.size.width) {
        _previousFrame = self.frame;
        [self fitToScrollView];
    }
}

- (void)reloadInputViews
{
    [super reloadInputViews];
    [_textView reloadInputViews];
}

- (void)setup
{
    self.showsVerticalScrollIndicator = NO;
    self.showsHorizontalScrollIndicator = NO;
    self.textView.textContainerInset = UIEdgeInsetsMake(8, 0, 8, 0);
    [self.textView setScrollEnabled:NO];
    self.textView.font = [UIFont systemFontOfSize:16];
    self.textView.backgroundColor = UIColor.clearColor;
    [self addSubview:self.textView];
    self.minNumberOfLines = 1;
    self.maxNumberOfLines = 3;
    [self updateMinimumAndMaximumHeight];
    WS(weakSelf);
    _textView.didChange = ^{
        [weakSelf fitToScrollView];
    };
    _textView.didUpdateHeightDependencies = ^{
        [weakSelf updateMinimumAndMaximumHeight];
    };
    
}

- (CGSize)measureTextViewSize
{
    CGSize size = [self.textView sizeThatFits:CGSizeMake(self.bounds.size.width, MAXFLOAT)];
    return CGSizeMake(size.width, MAX(size.height, _minHeight));
}

- (CGRect)measureFrame:(CGSize)contentSize
{
    CGSize selfSize = CGSizeZero;
    self.scrollEnabled = NO;
    if (contentSize.height < _minHeight || !_textView.hasText) {
        selfSize = CGSizeMake(contentSize.width, _minHeight);
    }else if (_maxHeight > 0 && contentSize.height > _maxHeight) {
        selfSize = CGSizeMake(contentSize.width, _maxHeight);
        self.scrollEnabled = YES;
    }else {
        selfSize = contentSize;
    }
    
    CGRect _frame = self.frame;
    _frame.size.height = selfSize.height;
    return _frame;
}

- (void)fitToScrollView
{
    CGFloat shouldScrollToBottom = self.contentOffset.y == self.contentSize.height - self.frame.size.height;
    CGSize actualTextViewSize = [self measureTextViewSize];
    CGRect oldScrollViewFrame = self.frame;
    
    CGRect _frame = self.bounds;
    _frame.origin = CGPointZero;
    _frame.size.height = actualTextViewSize.height;
    _textView.frame = _frame;
    self.contentSize = _frame.size;
    
    CGRect newScrollViewFrame = [self measureFrame:actualTextViewSize];
    
    if (oldScrollViewFrame.size.height != newScrollViewFrame.size.height && newScrollViewFrame.size.height <= _maxHeight) {
        [self flashScrollIndicators];
        [self.delegates willChangeHeight:newScrollViewFrame.size.height];
    }
    self.frame = newScrollViewFrame;
    if (shouldScrollToBottom) {
        [self scrollToBottom];
    }
    [self invalidateIntrinsicContentSize];
    [self.delegates didChangeHeight:self.frame.size.height];
}

- (void)scrollToBottom
{
    if (_isAutomaticScrollToBottomEnabled) {
        CGPoint point = self.contentOffset;
        point.y = self.contentSize.height - self.frame.size.height;
        self.contentOffset = point;
    }
}

- (void)updateMinimumAndMaximumHeight
{
    self.minHeight = [self simulateHeight:self.minNumberOfLines];
    //
    self.minHeight = MAX(36, self.minHeight);
    self.maxHeight = [self simulateHeight:self.maxNumberOfLines];
    [self fitToScrollView];
}

- (CGFloat)simulateHeight:(NSInteger )line
{
    NSString *saveText = self.textView.text;
    NSString *newText = @"-";
    self.textView.hidden = YES;

    for (NSInteger i = 0; i < line - 1; i ++) {
        newText = [NSString stringWithFormat:@"%@\n|W|",newText];
    }
    [self.textView setText:newText];
    CGFloat height = [self measureTextViewSize].height;
    
    self.textView.text = saveText;
    self.textView.hidden = NO;
    
    return height;
}

- (void)setMinNumberOfLines:(NSInteger)minNumberOfLines
{
    if (minNumberOfLines <= 1) {
        _minNumberOfLines = 1;
    }
    _minNumberOfLines = minNumberOfLines;
    _minHeight = [self simulateHeight:_minNumberOfLines];
}

- (void)setMaxNumberOfLines:(NSInteger)maxNumberOfLines
{
    if (maxNumberOfLines <= 1) {
        maxNumberOfLines = 1;
    }
    _maxNumberOfLines = maxNumberOfLines;
    _maxHeight = [self simulateHeight:_maxNumberOfLines];
}

- (NSAttributedString *)placeholderAttributedText
{
    return _textView.placeholderAttributedText;
}

- (UIView *)inputView
{
    return _textView.inputView;
}

- (BOOL)isFirstResponder
{
    return _textView.isFirstResponder;
}

- (BOOL)becomeFirstResponder
{
    return _textView.becomeFirstResponder;
}

- (CGSize)intrinsicContentSize
{
    return [self measureFrame:[self measureTextViewSize]].size;
}

- (void)setPlaceholderAttributedText:(NSAttributedString *)placeholderAttributedText
{
    _textView.placeholderAttributedText = placeholderAttributedText;
}

@end
