/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import "WXVideoComponent.h"
#import "WXHandlerFactory.h"
#import "WXURLRewriteProtocol.h"
#import "WXSDKEngine.h"
#import "WXImgLoaderProtocol.h"

#import <AVFoundation/AVPlayer.h>
#import <AVKit/AVPlayerViewController.h>
#import <AVFoundation/AVPlayerItem.h>

@interface WXPlayer : NSObject

@end

@implementation WXPlayer

@end

@interface WXVideoView()

@property (nonatomic, strong) UIViewController *playerViewController;
@property (nonatomic, strong) AVPlayerItem *playerItem;
@property (nonatomic, strong) WXSDKInstance *weexSDKInstance;
@property (nonatomic, strong) UIImageView *posterImageView;
@property (nonatomic, strong) id<WXImageOperationProtocol> imageOperation;
@property (nonatomic, assign) BOOL playerDidPlayed;

@end

@implementation WXVideoView

- (id)init
{
    if (self = [super init]) {
        _playerViewController = [AVPlayerViewController new];
        
        [self addSubview:_playerViewController.view];
    }
    return self;
}

- (void)dealloc
{
    _weexSDKInstance = nil;
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    [AVVC.player removeObserver:self forKeyPath:@"rate"];
    [_playerItem removeObserver:self forKeyPath:@"status"];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object: _playerItem];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSString *,id> *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"rate"]) {
        float rate = [change[NSKeyValueChangeNewKey] floatValue];
        if (rate == 0.0) {
            if (_playbackStateChanged)
                _playbackStateChanged(WXPlaybackStatePaused);
        } else if (rate == 1.0) {
            if (_playbackStateChanged)
                _playbackStateChanged(WXPlaybackStatePlaying);
        } else if (rate == -1.0) {//!OCLint
            // Reverse playback
        }
    } else if ([keyPath isEqualToString:@"status"]) {
        NSInteger status = [change[NSKeyValueChangeNewKey] integerValue];
        if (status == AVPlayerStatusFailed) {
            if (_playbackStateChanged)
                _playbackStateChanged(WXPlaybackStateFailed);
        }
    }
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    
    CGRect videoFrame = frame;
    videoFrame.origin.x = 0;
    videoFrame.origin.y = 0;
    [_playerViewController.view setFrame:videoFrame];
}

- (void)setURL:(NSURL *)URL
{
    NSString *newURL = [URL.absoluteString copy];
    WX_REWRITE_URL(URL.absoluteString, WXResourceTypeVideo, self.weexSDKInstance)
    
    if (!newURL) {
        return;
    }
    NSURL *videoNewURL = [NSURL URLWithString:newURL];
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    if (AVVC.player && _playerItem) {
        [_playerItem removeObserver:self forKeyPath:@"status"];
        [AVVC.player removeObserver:self forKeyPath:@"rate"];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object: _playerItem];
    }
    _playerItem = [[AVPlayerItem alloc] initWithURL:videoNewURL];
    AVPlayer *player = [AVPlayer playerWithPlayerItem: _playerItem];
    AVVC.player = player;
    
    [player addObserver:self
             forKeyPath:@"rate"
                options:NSKeyValueObservingOptionNew
                context:NULL];
    
    [_playerItem addObserver:self
                  forKeyPath:@"status"
                     options:NSKeyValueObservingOptionNew
                     context:NULL];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinish) name:AVPlayerItemDidPlayToEndTimeNotification object: _playerItem];
}

- (void)setPosterURL:(NSURL *)posterURL
{
    if (!posterURL) {
        return;
    }
    
    [self cancelImage];
    __weak typeof(self) weakSelf = self;
    weakSelf.imageOperation = [[self imageLoader] downloadImageWithURL:posterURL.absoluteString imageFrame:self.posterImageView.frame
                                                              userInfo:@{@"instanceId":self.weexSDKInstance.instanceId}
                                                             completed:^(UIImage *image, NSError *error, BOOL finished)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(self) strongSelf = weakSelf;
            if (!error) {
                strongSelf.posterImageView.image = image;
                strongSelf.posterImageView.hidden = strongSelf.playerDidPlayed;
            }
        });
    }];
}

- (void)setControlShow:(BOOL)showControl
{
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    AVVC.showsPlaybackControls = showControl;
}

- (void)playFinish
{
    if (_playbackStateChanged)
        _playbackStateChanged(WXPlaybackStatePlayFinish);
    
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    [[AVVC player] seekToTime:CMTimeMultiply([AVVC player].currentTime, 0)];
}

- (void)play
{
    _posterImageView.hidden = YES;
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    [[AVVC player] play];
}

- (void)pause
{
    AVPlayerViewController *AVVC = (AVPlayerViewController*)_playerViewController;
    [[AVVC player] pause];
}

- (void)posterTapHandler {
    if (self.posterClickHandle) {
        self.posterClickHandle();
    }
}

- (UIImageView *)posterImageView {
    if (!_posterImageView) {
        _posterImageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _posterImageView.userInteractionEnabled = YES;
        [_posterImageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(posterTapHandler)]];
        _posterImageView.hidden = YES;
        [self addSubview:_posterImageView];
        [self bringSubviewToFront:_posterImageView];
    }
    return _posterImageView;
}

- (id<WXImgLoaderProtocol>)imageLoader
{
    static id<WXImgLoaderProtocol> imageLoader;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        imageLoader = [WXHandlerFactory handlerForProtocol:@protocol(WXImgLoaderProtocol)];
    });
    return imageLoader;
}

- (void)cancelImage
{
    [_imageOperation cancel];
    _imageOperation = nil;
}

@end

@interface WXVideoComponent()

@property (nonatomic, weak) WXVideoView *videoView;
@property (nonatomic, strong) NSURL *videoURL;
@property (nonatomic, strong) NSURL *posterURL;
@property (nonatomic) BOOL autoPlay;
@property (nonatomic) BOOL playStatus;
@property (nonatomic) BOOL showControl;

@end

@implementation WXVideoComponent

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance {
    self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
    if (self) {
        if (attributes[@"src"]) {
            _videoURL = [NSURL URLWithString: attributes[@"src"]];
        }
        if (attributes[@"autoPlay"]) {
            _autoPlay = [attributes[@"autoPlay"] boolValue];
        }
        if ([attributes[@"playStatus"] compare:@"play" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
            _playStatus = true;
        }
        if ([attributes[@"playStatus"] compare:@"pause" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
            _playStatus = false;
        }
        if (attributes[@"poster"]) {
            _posterURL = [NSURL URLWithString: attributes[@"poster"]];
        }
        if (attributes[@"controls"]) {
            _showControl = ![attributes[@"controls"] isEqualToString:@"nocontrols"];
        }
    }
    return self;
}

- (UIView *)loadView
{
    WXVideoView* videoView = [[WXVideoView alloc] init];
    videoView.weexSDKInstance = self.weexInstance;
    return videoView;
}

- (void)viewDidLoad
{
    _videoView = (WXVideoView *)self.view;
    _videoView.layer.mask = [self drawBorderRadiusMaskLayer:_videoView.bounds];
    [_videoView setURL:_videoURL];
    [_videoView setPosterURL:_posterURL];
    [_videoView setControlShow:_showControl];
    
    __weak __typeof__(self) weakSelf = self;
    _videoView.posterClickHandle = ^{
        [weakSelf.videoView play];
    };
    _videoView.playbackStateChanged = ^(WXPlaybackState state) {
        NSString *eventType = nil;
        switch (state) {
            case WXPlaybackStatePlaying:
                eventType = @"start";
                break;
            case WXPlaybackStatePaused:
                eventType = @"pause";
                break;
            case WXPlaybackStatePlayFinish:
                eventType = @"finish";
                break;
            case WXPlaybackStateFailed:
                eventType = @"fail";
                break;
                
            default:
                NSCAssert(NO, @"");//!OCLint
                break;
        }
        [weakSelf fireEvent:eventType params:nil];
    };
    if (_playStatus) {
        [_videoView play];
    } else {
        [_videoView pause];
    }
    if (_autoPlay) {
        [_videoView play];
    }
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    if (attributes[@"src"]) {
        _videoURL = [NSURL URLWithString: attributes[@"src"]];
        [_videoView setURL:_videoURL];
    }
    if (attributes[@"autoPlay"]) {
        _autoPlay = [attributes[@"autoPlay"] boolValue];
        [_videoView play];
    }
    if ([attributes[@"playStatus"] compare:@"play" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        _playStatus = true;
        [_videoView play];
    }
    if ([attributes[@"playStatus"] compare:@"pause" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        _playStatus = false;
        [_videoView pause];
    }
    if (attributes[@"poster"]) {
        _posterURL = [NSURL URLWithString: attributes[@"poster"]];
        [_videoView setPosterURL:_posterURL];
    }
    if (attributes[@"controls"]) {
        _showControl = ![attributes[@"controls"] isEqualToString:@"nocontrols"];
        [_videoView setControlShow:_showControl];
    }
}

@end
