#import "TGProgressWindow.h"

#import "LegacyComponentsInternal.h"

#import "TGProgressSpinnerView.h"

static bool TGProgressWindowIsLight = true;

@interface TGProgressWindowController ()
{
    bool _light;
    UIVisualEffectView *_effectView;
    UIView *_backgroundView;
    TGProgressSpinnerView *_spinner;
}

@property (nonatomic, weak) UIWindow *weakWindow;
@property (nonatomic, strong) UIView *containerView;

@end

@implementation TGProgressWindowController

- (instancetype)init {
    return [self initWithLight:TGProgressWindowIsLight];
}

- (instancetype)initWithLight:(bool)light
{
    self = [super init];
    if (self != nil)
    {
        _light = light;
    }
    return self;
}

- (void)loadView
{
    [super loadView];

    _containerView = [[UIView alloc] initWithFrame:CGRectMake(CGFloor(self.view.frame.size.width - 100) / 2, CGFloor(self.view.frame.size.height - 100) / 2, 100, 100)];
    _containerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
    _containerView.alpha = 0.0f;
    _containerView.clipsToBounds = true;
    _containerView.layer.cornerRadius = 20.0f;
    _containerView.userInteractionEnabled = false;
    [self.view addSubview:_containerView];
    
    if (iosMajorVersion() >= 9)
    {
        _effectView = [[UIVisualEffectView alloc] initWithEffect:_light ? [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight] : [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
        _effectView.frame = _containerView.bounds;
        [_containerView addSubview:_effectView];
        
        if (_light)
        {
            UIView *tintView = [[UIView alloc] initWithFrame:_effectView.bounds];
            tintView.backgroundColor = UIColorRGBA(0xf4f4f4, 0.75f);
            [_containerView addSubview:tintView];
        }
    }
    else
    {
        _backgroundView = [[UIView alloc] initWithFrame:_containerView.bounds];
        _backgroundView.backgroundColor = _light ? UIColorRGBA(0xeaeaea, 0.92f) : UIColorRGBA(0x000000, 0.9f);
        [_containerView addSubview:_backgroundView];
    }
    
    _spinner = [[TGProgressSpinnerView alloc] initWithFrame:CGRectMake((_containerView.frame.size.width - 48.0f) / 2.0f, (_containerView.frame.size.height - 48.0f) / 2.0f, 48.0f, 48.0f) light:_light];
    [_containerView addSubview:_spinner];
    
    self.view.userInteractionEnabled = true;
    [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)]];
}

- (void)tapGesture:(UITapGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        if (_cancelled) {
            _cancelled();
        }
    }
}

- (void)updateLayout {
    _containerView.frame = CGRectMake(CGFloor(self.view.frame.size.width - 100) / 2, CGFloor(self.view.frame.size.height - 100) / 2, 100, 100);
    _spinner.frame = CGRectMake((_containerView.frame.size.width - 48.0f) / 2.0f, (_containerView.frame.size.height - 48.0f) / 2.0f, 48.0f, 48.0f);
}

- (void)show:(bool)animated
{
    UIWindow *window = _weakWindow;
    
    window.userInteractionEnabled = true;
    window.hidden = false;
    
    [_spinner setProgress];
    
    if (animated)
    {
        _containerView.transform = CGAffineTransformMakeScale(0.6f, 0.6f);
        if (iosMajorVersion() >= 7)
        {
            [UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^{
                _containerView.transform = CGAffineTransformIdentity;
            } completion:nil];
        }
        
        [UIView animateWithDuration:0.3f animations:^
        {
            _containerView.alpha = 1.0f;
            if (iosMajorVersion() < 7)
                _containerView.transform = CGAffineTransformIdentity;
        }];
    }
    else
        _containerView.alpha = 1.0f;
}

- (void)dismiss:(bool)animated {
    [self dismiss:animated completion:nil];
}

- (void)dismiss:(bool)animated completion:(void (^)(void))completion
{
    TGProgressWindow *window = (TGProgressWindow *)_weakWindow;
    
    window.userInteractionEnabled = false;
    if (animated)
    {
        [UIView animateWithDuration:0.3f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
        {
            _containerView.alpha = 0.0f;
        } completion:^(BOOL finished)
        {
            if (completion) {
                completion();
            }
            if (finished)
            {
                window.hidden = true;
                
                if (window == nil || window.skipMakeKeyWindowOnDismiss)
                    return;
                
                NSArray *windows = [[LegacyComponentsGlobals provider] applicationWindows];
                for (int i = (int)windows.count - 1; i >= 0; i--)
                {
                    if ([windows objectAtIndex:i] != window) {
                        [[windows objectAtIndex:i] makeKeyWindow];
                    }
                }
            }
        }];
    }
    else
    {
        _containerView.alpha = 0.0f;
        window.hidden = true;
        
        if (window == nil || window.skipMakeKeyWindowOnDismiss) {
            if (completion) {
                completion();
            }
        }
        
        NSArray *windows = [[LegacyComponentsGlobals provider] applicationWindows];
        for (int i = (int)windows.count - 1; i >= 0; i--)
        {
            if ([windows objectAtIndex:i] != window) {
                [[windows objectAtIndex:i] makeKeyWindow];
            }
        }
        
        if (completion) {
            completion();
        }
    }
}

- (void)dismissWithSuccess:(void (^)(void))completion
{
    TGProgressWindow *window = (TGProgressWindow *)_weakWindow;
    
    window.userInteractionEnabled = false;
    
    void (^dismissBlock)(void) = ^
    {
        [UIView animateWithDuration:0.3 delay:0.55 options:0 animations:^
        {
            _containerView.alpha = 0.0f;
        } completion:^(BOOL finished)
        {
            if (finished)
            {
                if (completion) {
                    completion();
                }
                window.hidden = true;
                
                if (window == nil || window.skipMakeKeyWindowOnDismiss)
                    return;
                
                NSArray *windows = [[LegacyComponentsGlobals provider] applicationWindows];
                for (int i = (int)windows.count - 1; i >= 0; i--)
                {
                    if ([windows objectAtIndex:i] != window) {
                        [[windows objectAtIndex:i] makeKeyWindow];
                    }
                }
            }
        }];
    };
    
    if (window.hidden || window == nil)
    {
        window.hidden = false;
        _containerView.transform = CGAffineTransformMakeScale(0.6f, 0.6f);
        
        if (iosMajorVersion() >= 7)
        {
            [UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^{
                _containerView.transform = CGAffineTransformIdentity;
            } completion:nil];
        }

        [UIView animateWithDuration:0.3f animations:^
        {
             _containerView.alpha = 1.0f;
            if (iosMajorVersion() < 7)
                _containerView.transform = CGAffineTransformIdentity;
        } completion:^(__unused BOOL finished) {
            dismissBlock();
        }];
        
        TGDispatchAfter(0.15, dispatch_get_main_queue(), ^{
            [_spinner setSucceed];
        });
    }
    else
    {
        _spinner.onSuccess = ^{
            dismissBlock();
        };
        [_spinner setSucceed];
    }
}

- (BOOL)canBecomeFirstResponder {
    return false;
}

@end

@interface TGProgressWindow () {
    bool _dismissed;
    bool _appeared;
}

@end

@implementation TGProgressWindow

- (instancetype)init {
    return [self initWithFrame:[[UIScreen mainScreen] bounds]];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.windowLevel = UIWindowLevelStatusBar;
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        
        TGProgressWindowController *controller = [[TGProgressWindowController alloc] init];
        controller.weakWindow = self;
        self.rootViewController = controller;
        
        self.opaque = false;
    }
    return self;
}

- (void)showAnimated
{
    [self show:true];
}

- (void)showWithDelay:(NSTimeInterval)delay {
    __weak TGProgressWindow *weakSelf = self;
    TGDispatchAfter(delay, dispatch_get_main_queue(), ^{
        __strong TGProgressWindow *strongSelf = weakSelf;
        if (strongSelf != nil && !strongSelf->_dismissed) {
            [strongSelf show:true];
        }
    });
}

- (void)show:(bool)animated
{
    _appeared = true;
    [((TGProgressWindowController *)self.rootViewController) show:animated];
}

- (void)dismiss:(bool)animated
{
    if (!_dismissed) {
        _dismissed = true;
        self.userInteractionEnabled = false;
        
        [((TGProgressWindowController *)self.rootViewController) dismiss:animated];
    }
}

- (void)dismissWithSuccess
{
    if (!_dismissed) {
        _dismissed = true;
        [((TGProgressWindowController *)self.rootViewController) dismissWithSuccess:nil];
    }
}

+ (void)setDarkStyle:(bool)dark
{
    TGProgressWindowIsLight = !dark;
}

@end