#import "TGNeoMediaMessageViewModel.h"
#import "TGBridgeMessage.h"

#import "TGGeometry.h"

#import "TGMessageViewModel.h"

const UIEdgeInsets TGNeoMediaMessageViewModelInsets = { 1.5, 1.5, 5.0, 1.5 };
const CGFloat TGNeoMediaCaptionSpacing = 3.0f;

@interface TGNeoMediaMessageViewModel ()
{
    TGNeoLabelViewModel *_textModel;
    
    TGBridgeImageMediaAttachment *_imageAttachment;
    TGBridgeVideoMediaAttachment *_videoAttachment;
    TGBridgeLocationMediaAttachment *_locationAttachment;
}
@end

@implementation TGNeoMediaMessageViewModel

- (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)
    {
        bool hasHeader = (self.forwardHeaderModel != nil || self.replyHeaderModel != nil);
        NSString *caption = nil;
        
        for (TGBridgeMediaAttachment *attachment in message.media)
        {
            if ([attachment isKindOfClass:[TGBridgeImageMediaAttachment class]])
            {
                _imageAttachment = (TGBridgeImageMediaAttachment *)attachment;
                if (_imageAttachment.caption.length > 0)
                    caption = _imageAttachment.caption;
            }
            else if ([attachment isKindOfClass:[TGBridgeVideoMediaAttachment class]])
            {
                _videoAttachment = (TGBridgeVideoMediaAttachment *)attachment;
                if (_videoAttachment.caption.length > 0)
                    caption = _videoAttachment.caption;
            }
            else if ([attachment isKindOfClass:[TGBridgeLocationMediaAttachment class]])
            {
                _locationAttachment = (TGBridgeLocationMediaAttachment *)attachment;
            }
        }
        
        if (caption != nil)
        {
            _textModel = [[TGNeoLabelViewModel alloc] initWithText:caption font:[UIFont systemFontOfSize:[TGNeoBubbleMessageViewModel bodyTextFontSize]] color:[self normalColorForMessage:message] attributes:nil];
            [self addSubmodel:_textModel];
        }
        
        self.showBubble = (caption != nil) || hasHeader;
    }
    return self;
}

- (CGSize)contentContainerSizeWithImageSize:(CGSize)imageSize
{
    return CGSizeMake(imageSize.width + TGNeoMediaMessageViewModelInsets.left + TGNeoMediaMessageViewModelInsets.right - TGNeoBubbleMessageViewModelInsets.left - TGNeoBubbleMessageViewModelInsets.right, FLT_MAX);
}

- (CGSize)layoutWithContainerSize:(CGSize)containerSize
{
    CGSize imageSize;
    if (_imageAttachment != nil)
    {
        imageSize = [self imageSizeForAttachment:_imageAttachment containerSize:containerSize];
    }
    else if (_videoAttachment != nil)
    {
        imageSize = [self imageSizeForAttachment:_videoAttachment containerSize:containerSize];
    }
    else
    {
        switch (TGWatchScreenType())
        {
            case TGScreenType42mm:
                imageSize = CGSizeMake(142, 92);
                break;
                
            default:
                imageSize = CGSizeMake(125, 92);
                break;
        }
    }
    
    CGSize contentContainerSize = self.showBubble ? [self contentContainerSizeWithImageSize:imageSize] : containerSize;
    
    CGSize headerSize = [self layoutHeaderModelsWithContainerSize:contentContainerSize];
    CGFloat textTopOffset = headerSize.height;
    CGSize contentSize = CGSizeZero;
    
    if (self.forwardHeaderModel == nil && self.replyHeaderModel == nil && self.authorNameModel == nil)
    {
        textTopOffset = TGNeoMediaMessageViewModelInsets.top;
    }
    else if (self.showBubble)
    {
        textTopOffset += TGNeoBubbleHeaderSpacing;
    }
    else if (!self.showBubble)
    {
        if (self.authorNameModel != nil)
            textTopOffset += TGNeoBubbleHeaderSpacing;
        else
            textTopOffset = 0;
    }
    
    UIEdgeInsets contentInsets = self.showBubble ? TGNeoMediaMessageViewModelInsets : UIEdgeInsetsZero;
    
    UIEdgeInsets inset = UIEdgeInsetsMake(textTopOffset, contentInsets.left, 0, 0);
    if (_imageAttachment != nil || _videoAttachment != nil)
    {
        TGBridgeMediaAttachment *attachment = _imageAttachment ?: _videoAttachment;
        
        [self addAdditionalLayout:@
        {
            TGNeoContentInset: [NSValue valueWithUIEdgeInsets:inset],
            TGNeoMessageMediaImage: @
            {
                TGNeoMessageMediaImageSpinner: @true,
                TGNeoMessageMediaPlayButton: @(_videoAttachment != nil),
                TGNeoMessageMediaImageAttachment: attachment,
                TGNeoMessageMediaSize: [NSValue valueWithCGSize:imageSize]
            }
        } withKey:TGNeoMessageMediaGroup];
    }
    else if (_locationAttachment != nil)
    {
        [self addAdditionalLayout:@
        {
            TGNeoContentInset: [NSValue valueWithUIEdgeInsets:inset],
            TGNeoMessageMediaMap: @
            {
                TGNeoMessageMediaMapCoordinate: [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(_locationAttachment.latitude, _locationAttachment.longitude)],
                TGNeoMessageMediaSize: [NSValue valueWithCGSize:imageSize]
            }
        } withKey:TGNeoMessageMediaGroup];
    }
    
    contentSize.width = imageSize.width + contentInsets.left + contentInsets.right;
    
    if (_textModel != nil)
    {
        CGSize textSize = [_textModel contentSizeWithContainerSize:contentContainerSize];
        _textModel.frame = CGRectMake(TGNeoBubbleMessageViewModelInsets.left, textTopOffset + imageSize.height + TGNeoMediaCaptionSpacing, textSize.width, textSize.height);
        
        contentSize.height = CGRectGetMaxY(_textModel.frame) + TGNeoBubbleMessageViewModelInsets.bottom;
    }
    else
    {
        contentSize.height = textTopOffset + imageSize.height + contentInsets.bottom;
    }
    
    if (!self.showBubble)
    {
        contentSize.width = containerSize.width;
        contentSize.height += 3.5f;
    }
    
    [super layoutWithContainerSize:contentSize];
    
    return contentSize;
}

- (CGSize)imageSizeForAttachment:(TGBridgeMediaAttachment *)attachment containerSize:(CGSize)containerSize
{
    CGSize targetImageSize = CGSizeZero;
    
    if ([attachment isKindOfClass:[TGBridgeImageMediaAttachment class]])
        [((TGBridgeImageMediaAttachment *)attachment).imageInfo imageUrlForLargestSize:&targetImageSize];
    else if ([attachment isKindOfClass:[TGBridgeVideoMediaAttachment class]])
        targetImageSize = ((TGBridgeVideoMediaAttachment *)attachment).dimensions;
    
    CGSize screenSize = containerSize;
    
    CGSize mediaGroupSize = CGSizeZero;
    CGSize maxSize = CGSizeMake(screenSize.width - 15, screenSize.width);
    CGSize minSize = CGSizeMake(screenSize.width / 1.25f, screenSize.width / 2);
    [TGMessageViewModel imageBubbleSizeForImageSize:targetImageSize minSize:minSize maxSize:maxSize thumbnailSize:&mediaGroupSize renderSize:NULL];
    
    mediaGroupSize = CGSizeMake(ceilf(mediaGroupSize.width), ceilf(mediaGroupSize.height));
    
    return mediaGroupSize;
}

@end
