#import "TGNeoBubbleMessageViewModel.h"
#import "TGNeoBackgroundViewModel.h"

#import "TGExtensionDelegate.h"
#import "TGColor.h"

#import "TGBridgeContext.h"
#import "TGBridgeMessage.h"
#import "TGBridgeUser.h"

#import "TGPeerIdAdapter.h"

const UIEdgeInsets TGNeoBubbleMessageViewModelInsets = { 4.5, 11, 9, 11 };
const CGFloat TGNeoBubbleMessageMetaSpacing = 5.0f;
const CGFloat TGNeoBubbleHeaderSpacing = 2.0f;

@interface TGNeoBubbleMessageViewModel ()
{
    TGNeoBackgroundViewModel *_backgroundModel;
}
@end

@implementation TGNeoBubbleMessageViewModel

- (instancetype)initWithMessage:(TGBridgeMessage *)message type:(TGNeoMessageType)type users:(NSDictionary *)users context:(TGBridgeContext *)context
{
    self = [super initWithMessage:message type:type users:users context:context];
    if (self != nil)
    {
        self.showBubble = true;
        
        if (!message.outgoing && type == TGNeoMessageTypeGroup)
        {
            _authorNameModel = [[TGNeoLabelViewModel alloc] initWithText:[users[@(message.fromUid)] displayName] font:[UIFont systemFontOfSize:14] color:[TGColor colorForUserId:(int32_t)message.fromUid myUserId:context.userId] attributes:nil];
            [self addSubmodel:_authorNameModel];
        }
        
        TGBridgeForwardedMessageMediaAttachment *forwardAttachment = nil;
        TGBridgeReplyMessageMediaAttachment *replyAttachment = nil;
        for (TGBridgeMediaAttachment *attachment in message.media)
        {
            if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]])
                forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment;
            else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]])
                replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment;
        }
        
        if (forwardAttachment != nil)
        {
            if (TGPeerIdIsChannel(forwardAttachment.peerId))
            {
                _forwardHeaderModel = [[TGNeoForwardHeaderViewModel alloc] initWithForwardAttachment:forwardAttachment chat:users[@(forwardAttachment.peerId)] outgoing:message.outgoing];
            }
            else
            {
                _forwardHeaderModel = [[TGNeoForwardHeaderViewModel alloc] initWithForwardAttachment:forwardAttachment user:users[@(forwardAttachment.peerId)] outgoing:message.outgoing];
            }
            [self addSubmodel:_forwardHeaderModel];
        }
        
        if (replyAttachment != nil)
        {
            _replyHeaderModel = [[TGNeoReplyHeaderViewModel alloc] initWithReplyAttachment:replyAttachment users:users outgoing:message.outgoing];
            [self addSubmodel:_replyHeaderModel];
        }
    }
    return self;
}

- (CGSize)contentContainerSizeWithContainerSize:(CGSize)containerSize
{
    return CGSizeMake(containerSize.width - TGNeoBubbleMessageViewModelInsets.left - TGNeoBubbleMessageViewModelInsets.right, FLT_MAX);
}

- (CGSize)layoutHeaderModelsWithContainerSize:(CGSize)containerSize
{
    CGFloat textTopOffset = self.showBubble ? TGNeoBubbleMessageViewModelInsets.top : 0;
    CGFloat maxContentWidth = 0;
    if (self.authorNameModel != nil)
    {
        CGSize textSize = [self.authorNameModel contentSizeWithContainerSize:containerSize];
        self.authorNameModel.frame = CGRectMake(TGNeoBubbleMessageViewModelInsets.left, textTopOffset, textSize.width, 16.5f);
        textTopOffset += self.authorNameModel.frame.size.height;
            
        if (textSize.width > maxContentWidth)
            maxContentWidth = textSize.width;
    }
    
    if (self.replyHeaderModel != nil)
    {
        textTopOffset += TGNeoBubbleHeaderSpacing;
        
        CGSize headerSize = [self.replyHeaderModel contentSizeWithContainerSize:containerSize];
        self.replyHeaderModel.frame = CGRectMake(TGNeoBubbleMessageViewModelInsets.left, textTopOffset, headerSize.width, headerSize.height);
        if (headerSize.width > maxContentWidth)
            maxContentWidth = headerSize.width;
        
        textTopOffset += self.replyHeaderModel.frame.size.height + TGNeoBubbleHeaderSpacing;
        
        if (_replyHeaderModel.mediaAttachment != nil)
        {
            UIEdgeInsets inset = UIEdgeInsetsMake(self.replyHeaderModel.frame.origin.y + 1.5f, self.replyHeaderModel.frame.origin.x + TGNeoReplyHeaderLineWidth + TGNeoReplyHeaderSpacing, 0, 0);
            NSDictionary *imageDictionary = @{ TGNeoMessageReplyMediaAttachment: _replyHeaderModel.mediaAttachment };
            [self addAdditionalLayout:@{ TGNeoContentInset: [NSValue valueWithUIEdgeInsets:inset], TGNeoMessageReplyImageGroup: imageDictionary } withKey:TGNeoMessageHeaderGroup];
        }
    }
    
    if (self.forwardHeaderModel != nil)
    {
        textTopOffset += TGNeoBubbleHeaderSpacing;
        
        CGSize headerSize = [self.forwardHeaderModel contentSizeWithContainerSize:containerSize];
        self.forwardHeaderModel.frame = CGRectMake(TGNeoBubbleMessageViewModelInsets.left, textTopOffset, headerSize.width, headerSize.height);
        if (headerSize.width > maxContentWidth)
            maxContentWidth = headerSize.width;
        
        textTopOffset += self.forwardHeaderModel.frame.size.height + TGNeoBubbleHeaderSpacing;
    }
    
    return CGSizeMake(maxContentWidth, textTopOffset);
}

- (UIColor *)normalColorForMessage:(TGBridgeMessage *)message
{
    if (message.outgoing)
        return [UIColor whiteColor];
    else
        return [UIColor blackColor];
}

- (UIColor *)subtitleColorForMessage:(TGBridgeMessage *)message
{
    if (message.outgoing)
        return [UIColor hexColor:0xbeddf6];
    else
        return [UIColor hexColor:0x7e7e81];
}

- (UIColor *)accentColorForMessage:(TGBridgeMessage *)message
{
    if (message.outgoing)
        return [UIColor whiteColor];
    else
        return [UIColor hexColor:0x1f97f8];
}

- (CGSize)layoutWithContainerSize:(CGSize)containerSize
{
    self.contentSize = containerSize;
            
    return CGSizeZero;
}

+ (CGFloat)bodyTextFontSize
{
    TGContentSizeCategory category = [TGExtensionDelegate instance].contentSizeCategory;
    
    switch (category)
    {
        case TGContentSizeCategoryXS:
            return 14.0f;
            
        case TGContentSizeCategoryS:
            return 15.0f;
            
        case TGContentSizeCategoryL:
            return 16.0f;
            
        case TGContentSizeCategoryXL:
            return 17.0f;
            
        case TGContentSizeCategoryXXL:
            return 18.0f;
            
        case TGContentSizeCategoryXXXL:
            return 19.0f;
            
        default:
            break;
    }
    
    return 16.0f;
}

@end
