/*
 * 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 "WXEmbedComponent.h"
#import "WXComponent_internal.h"
#import "WXSDKInstance_private.h"
#import "WXComponent+Navigation.h"
#import "WXSDKInstance.h"
#import "WXSDKManager.h"
#import "WXConvert.h"
#import "WXUtility.h"
#import "WXApmForInstance.h"

@interface WXEmbedComponent ()

@property (nonatomic, strong) WXSDKInstance *embedInstance;
@property (nonatomic, strong) UIView *embedView;
@property (nonatomic, assign) BOOL createFinished;
@property (nonatomic, assign) BOOL renderFinished;
@property (nonatomic, assign) WXVisibility visible;
@property (nonatomic, strong) NSURL *sourceURL;
@property (nonatomic, strong) WXErrorView *errorView;

@end

@implementation WXEmbedComponent 

#pragma mark Life Cycle

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    if (self.embedInstance) {
        [self.embedInstance destroyInstance];
    }
}

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        
        _createFinished = NO;
        _renderFinished = NO;
        
        _sourceURL = [NSURL URLWithString: attributes[@"src"]];
        _visible =  [WXConvert WXVisibility:styles[@"visibility"]];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(observeInstanceState:) name:WX_INSTANCE_NOTIFICATION_UPDATE_STATE object:nil];
    }
    
    return self;
}

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    [self _layoutEmbedView];
}

- (void)updateStyles:(NSDictionary *)styles
{
    [super updateStyles:styles];
    
    if (styles[@"visibility"]) {
        WXVisibility visible = [WXConvert WXVisibility:styles[@"visibility"]];
        if (_visible != visible) {
            _visible = visible;
            [self _layoutEmbedView];
        }
    }
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    [super updateAttributes:attributes];
    
    if (attributes[@"src"]) {
        NSURL *sourceURL = [NSURL URLWithString:attributes[@"src"]];
        if (!sourceURL|| ![[sourceURL absoluteString] isEqualToString:[_sourceURL absoluteString]]) {
            _sourceURL = sourceURL;
            _createFinished = NO;
            [self _layoutEmbedView];
        }
    }
}

- (void)refreshWeex
{
    [self _renderWithURL:_sourceURL];
}

- (void)_layoutEmbedView
{
    if (_visible == WXVisibilityShow) {
        [self _updateState:WeexInstanceAppear];
        if (!_createFinished && !CGRectEqualToRect(CGRectZero, self.calculatedFrame)) {
            [self _renderWithURL:_sourceURL];
        }
    }
    else {
        [self _updateState:WeexInstanceDisappear];
    }
}

- (void)_renderWithURL:(NSURL *)sourceURL
{
    if (!sourceURL || [[sourceURL absoluteString] length] == 0) {
        return;
    }
    
    [_embedInstance destroyInstance];
    _embedInstance = [[WXSDKInstance alloc] init];
    _embedInstance.parentInstance = self.weexInstance;
    _embedInstance.parentNodeRef = self.ref;
    _embedInstance.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height);
    _embedInstance.pageName = sourceURL.absoluteString;
    _embedInstance.pageObject = self.weexInstance.viewController;
    _embedInstance.viewController = self.weexInstance.viewController;
    
    NSString *newURL = nil;
    
    if ([sourceURL.absoluteString rangeOfString:@"?"].location != NSNotFound) {
        newURL = [NSString stringWithFormat:@"%@&random=%d", sourceURL.absoluteString, arc4random()];
    }
    else {
        newURL = [NSString stringWithFormat:@"%@?random=%d", sourceURL.absoluteString, arc4random()];
    }
    
    [_embedInstance renderWithURL:[NSURL URLWithString:newURL] options:@{@"bundleUrl":[sourceURL absoluteString]} data:nil];
    [_embedInstance.apmInstance setProperty:KEY_PAGE_PROPERTIES_INSTANCE_TYPE withValue:@"embed"];
    [_embedInstance.apmInstance setProperty:KEY_PAGE_PROPERTIES_PARENT_PAGE withValue:_embedInstance.parentInstance.pageName];
    [self.weexInstance.apmInstance updateDiffStats:KEY_PAGE_STATS_EMBED_COUNT withDiffValue:1];
    __weak typeof(self) weakSelf = self;
    _embedInstance.onCreate = ^(UIView *view) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (weakSelf.errorView) {
                [weakSelf.errorView removeFromSuperview];
                weakSelf.errorView = nil;
            }
        
            [weakSelf.embedView removeFromSuperview];
            weakSelf.embedView = view;
            [weakSelf.view addSubview:weakSelf.embedView];
            
            weakSelf.createFinished = YES;
        });
    };
    
    _embedInstance.onFailed = ^(NSError *error) {
        weakSelf.weexInstance.apmInstance.isDegrade = YES;
        dispatch_async(dispatch_get_main_queue(), ^{
            if (weakSelf.errorView) {
                return ;
            }
            
            WXErrorView *errorView = [[WXErrorView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 135.0f, 130.0f)];
            errorView.center = CGPointMake(weakSelf.view.bounds.size.width / 2.0f, weakSelf.view.bounds.size.height / 2.0f);
            errorView.delegate = weakSelf;
            [weakSelf.view addSubview:errorView];
            
            weakSelf.errorView = errorView;
        });
    };
    
    _embedInstance.renderFinish = ^(UIView *view) {
         weakSelf.renderFinished = YES;
        [weakSelf _updateState:WeexInstanceAppear];
    };
}

- (void)_updateState:(WXState)state
{
    if (_renderFinished && _embedInstance && _embedInstance.state != state) {
        _embedInstance.state = state;
        
        if (state == WeexInstanceAppear) {
            [self setNavigationWithStyles:self.embedInstance.naviBarStyles];
            [[WXSDKManager bridgeMgr] fireEvent:self.embedInstance.instanceId ref:WX_SDK_ROOT_REF type:@"viewappear" params:nil domChanges:nil];
        }
        else if (state == WeexInstanceDisappear) {
            [[WXSDKManager bridgeMgr] fireEvent:self.embedInstance.instanceId ref:WX_SDK_ROOT_REF type:@"viewdisappear" params:nil domChanges:nil];
        }
    }
}

- (void)_frameDidCalculated:(BOOL)isChanged
{
    [super _frameDidCalculated:isChanged];
    self.embedInstance.frame = self.calculatedFrame;
}

- (void)onclickErrorView
{
    if (self.errorView) {
        [self.errorView removeFromSuperview];
        self.errorView = nil;
    }
    
    [self _renderWithURL:self.sourceURL];
}

- (void)observeInstanceState:(NSNotification *)notification
{
    WXSDKInstance *instance = notification.object;
    
    if (instance == self.weexInstance) {
        NSDictionary *userInfo = notification.userInfo;
        WXState state = [userInfo[@"state"] integerValue];
        if (_visible == WXVisibilityHidden) {
            switch (state) {
                case WeexInstanceBackground:
                    [self _updateState:WeexInstanceBackground];
                    break;
                default:
                    [self _updateState:WeexInstanceDisappear];
                    break;
            }
        }
        else {
            [self _updateState:state];
        }
    }
}

@end
