// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.

import UIKit
import SessionUIKit

open class ScreenLockViewController: UIViewController {
    public enum State {
        case none
        
        /// Shown while app is inactive or background, if enabled.
        case protection
        
        /// Shown while app is active, if enabled.
        case lock
    }
    
    public override var preferredStatusBarStyle: UIStatusBarStyle {
        return ThemeManager.currentTheme.statusBarStyle
    }
    
    public override var canBecomeFirstResponder: Bool { true }
    
    public var onUnlockPressed: (() -> ())?
    private var screenBlockingSignature: String?
    
    // MARK: - UI
    
    private let logoView: UIImageView = {
        let result: UIImageView = UIImageView(image: #imageLiteral(resourceName: "SessionGreen64"))
        result.contentMode = .scaleAspectFit
        result.isHidden = true
        
        return result
    }()
    
    public lazy var unlockButton: SessionButton = {
        let result: SessionButton = SessionButton(style: .bordered, size: .medium)
        result.translatesAutoresizingMaskIntoConstraints = false
        result.setTitle("Unlock Session", for: .normal)
        result.addTarget(self, action: #selector(showUnlockUI), for: .touchUpInside)
        result.isHidden = true
        
        // Need to match the launch screen so force the styling to be the primary green
        result.setThemeTitleColorForced(.primary(.green), for: .normal)
        result.setThemeBackgroundColorForced(.primary(.green), for: .highlighted)
        result.themeBorderColorForced = .primary(.green)

        return result
    }()
    
    // MARK: - Lifecycle
                                  
    public init(onUnlockPressed: (() -> ())? = nil) {
        self.onUnlockPressed = onUnlockPressed
        
        super.init(nibName: nil, bundle: nil)
    }
                                  
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
                                  
    open override func loadView() {
        super.loadView()
        
        view.themeBackgroundColorForced = .theme(.classicDark, color: .black)  // Need to match the Launch screen

        let edgesView: UIView = UIView.container()
        self.view.addSubview(edgesView)
        edgesView.pin(to: view)
        
        edgesView.addSubview(logoView)
        logoView.center(in: edgesView)
        logoView.set(.width, to: 64)
        logoView.set(.height, to: 64)

        edgesView.addSubview(unlockButton)
        unlockButton.pin(.top, to: .bottom, of: logoView, withInset: Values.mediumSpacing)
        unlockButton.center(.horizontal, in: view)
        
        updateUI(state: .protection, animated: false)
    }
    
    /// The "screen blocking" window has three possible states:
    ///
    /// * "Just a logo".  Used when app is launching and in app switcher.  Must match the "Launch Screen" storyboard pixel-for-pixel.
    /// * "Screen Lock, local auth UI presented". Must match the "Launch Screen" storyboard pixel-for-pixel.
    /// * "Screen Lock, local auth UI not presented". Show "unlock" button.
    public func updateUI(state: State, animated: Bool) {
        guard isViewLoaded else { return }

        let shouldShowBlockWindow: Bool = (state != .none)
        let shouldHaveScreenLock: Bool = (state == .lock)

        self.logoView.isHidden = !shouldShowBlockWindow

        let signature: String = String(format: "%d", shouldHaveScreenLock)
        
        // Skip redundant work to avoid interfering with ongoing animations
        guard signature != self.screenBlockingSignature else { return }
        
        self.unlockButton.isHidden = !shouldHaveScreenLock
        self.screenBlockingSignature = signature

        guard animated else {
            self.view.setNeedsLayout()
            return
        }
        
        UIView.animate(withDuration: 0.3) { [weak self] in
            self?.view.layoutIfNeeded()
        }
    }
    
    @objc private func showUnlockUI() {
        self.onUnlockPressed?()
    }
}