#import "TGEmbedVimeoPlayerView.h"
#import "TGEmbedPlayerState.h"

NSString *const TGVimeoPlayerCallbackOnReady = @"onReady";
NSString *const TGVimeoPlayerCallbackOnState = @"onState";

@interface TGEmbedVimeoPlayerView ()
{
    NSString *_videoId;
    
    bool _started;
    bool _initiallyPlayed;
    
    NSInteger _ignorePositionUpdates;
}
@end

@implementation TGEmbedVimeoPlayerView

- (instancetype)initWithWebPageAttachment:(TGWebPageMediaAttachment *)webPage thumbnailSignal:(SSignal *)thumbnailSignal
{
    self = [super initWithWebPageAttachment:webPage thumbnailSignal:thumbnailSignal];
    if (self != nil)
    {
        _videoId = [TGEmbedVimeoPlayerView _vimeoVideoIdFromText:webPage.embedUrl];
    }
    return self;
}

- (void)playVideo
{
    [super playVideo];
    
    if (_initiallyPlayed)
    {
        [self _evaluateJS:@"player.api('play');" completion:nil];
    }
    else
    {
        [self _evaluateJS:@"injectCmd('initialPlay')" completion:nil];
        _initiallyPlayed = true;
    }
    
    _ignorePositionUpdates = 2;
}

- (void)pauseVideo:(bool)manually
{
    [super pauseVideo:manually];
    [self _evaluateJS:@"player.api('pause');" completion:nil];
}

- (void)seekToPosition:(NSTimeInterval)position
{
    NSString *command = [NSString stringWithFormat:@"player.api('seekTo', %@);", @(position)];
    [self _evaluateJS:command completion:nil];
    
    TGEmbedPlayerState *newState = [TGEmbedPlayerState stateWithPlaying:self.state.isPlaying duration:self.state.duration position:position downloadProgress:self.state.downloadProgress];
    [self updateState:newState];
    
    _ignorePositionUpdates = 2;
}

- (TGEmbedPlayerControlsType)_controlsType
{
    return TGEmbedPlayerControlsTypeFull;
}

- (void)_onPageReady
{
    
}

- (void)_didBeginPlayback
{
    [super _didBeginPlayback];
    
    TGDispatchAfter(0.5, dispatch_get_main_queue(), ^
    {
        [self setDimmed:false animated:true shouldDelay:false];
    });
}

- (void)_notifyOfCallbackURL:(NSURL *)url
{
    NSString *action = url.host;
    
    NSString *query = url.query;
    NSString *data;
    if (query != nil)
        data = [query componentsSeparatedByString:@"="][1];
    
    if ([action isEqual:TGVimeoPlayerCallbackOnReady])
    {
        
    }
    else if ([action isEqualToString:TGVimeoPlayerCallbackOnState])
    {
        NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:false];
        NSArray *queryItems = urlComponents.queryItems;
        
        bool playing = self.state.playing;
        bool finished = false;
        NSTimeInterval position = self.state.position;
        NSTimeInterval duration = self.state.duration;
        CGFloat downloadProgress = self.state.downloadProgress;

        for (NSURLQueryItem *queryItem in queryItems)
        {
            if ([queryItem.name isEqualToString:@"playback"])
            {
                playing = ([queryItem.value integerValue] == 1);
                finished = ([queryItem.value integerValue] == 2);
            }
            else if ([queryItem.name isEqualToString:@"position"])
            {
                if (_ignorePositionUpdates > 0)
                    _ignorePositionUpdates--;
                else
                    position = [queryItem.value doubleValue];
            }
            else if ([queryItem.name isEqualToString:@"duration"])
            {
                duration = [queryItem.value doubleValue];
            }
            else if ([queryItem.name isEqualToString:@"download"])
            {
                downloadProgress = [queryItem.value floatValue];
            }
        }
        
        if (!_started && playing)
        {
            _started = true;
            [self _didBeginPlayback];
        }
        
        if (finished)
            position = 0.0;
        
        TGEmbedPlayerState *newState = [TGEmbedPlayerState stateWithPlaying:playing duration:duration position:position downloadProgress:downloadProgress];
        [self updateState:newState];
    }
}

- (NSString *)_embedHTML
{
    NSError *error = nil;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"VimeoPlayer" ofType:@"html"];
    
    NSString *embedHTMLTemplate = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if (error != nil)
    {
        TGLog(@"[VimeoEmbedPlayer]: Received error rendering template: %@", error);
        return nil;
    }
    
    NSString *autoplay = self.disallowAutoplay ? @"false" : @"true";
    NSString *embedHTML = [NSString stringWithFormat:embedHTMLTemplate, _videoId, autoplay];
    return embedHTML;
}

- (NSURL *)_baseURL
{
    return [NSURL URLWithString:@"https://player.vimeo.com/"];
}

- (void)_setupUserScripts:(WKUserContentController *)contentController
{
    NSError *error = nil;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"VimeoPlayerInject" ofType:@"js"];
    NSString *scriptText = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if (error != nil)
        TGLog(@"[VimeoEmbedPlayer]: Received error loading inject script: %@", error);
    
    WKUserScript *script = [[WKUserScript alloc] initWithSource:scriptText injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:false];
    [contentController addUserScript:script];
}

- (bool)_scaleViewToMaxSize
{
    return true;
}

+ (NSString *)_vimeoVideoIdFromText:(NSString *)text
{
    if ([text hasPrefix:@"http://player.vimeo.com/video/"] || [text hasPrefix:@"https://player.vimeo.com/video/"])
    {
        NSString *suffix = @"";
        
        NSMutableArray *prefixes = [NSMutableArray arrayWithArray:@
        [
            @"http://player.vimeo.com/video/",
            @"https://player.vimeo.com/video/"
        ]];
        
        while (suffix.length == 0 && prefixes.count > 0)
        {
            NSString *prefix = prefixes.firstObject;
            if ([text hasPrefix:prefix])
            {
                suffix = [text substringFromIndex:prefix.length];
                break;
            }
            else
            {
                [prefixes removeObjectAtIndex:0];
            }
        }
        
        for (int i = 0; i < (int)suffix.length; i++)
        {
            unichar c = [suffix characterAtIndex:i];
            if (!((c >= '0' && c <= '9')))
                break;
        }
        
        return suffix;
    }
    
    return nil;
}

+ (bool)_supportsWebPage:(TGWebPageMediaAttachment *)webPage
{
    NSString *url = webPage.embedUrl;
    return ([url hasPrefix:@"http://player.vimeo.com/video/"] || [url hasPrefix:@"https://player.vimeo.com/video/"]);
}

@end
