//
//  UIColor+Extension.swift
//  MVMCoreUI
//
//  Created by Kevin Christiano on 10/24/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit

public typealias ColorHexTuple = (uiColor: UIColor, hex: String)


extension UIColor {
    //--------------------------------------------------
    // MARK: - Convenience Dictionary
    //--------------------------------------------------
    
    /// Dictionary to access brand approved colors by name.
    public static let names: [String: ColorHexTuple] = ["black": (.mvmBlack, "#000000"),
                                                        "white": (.mvmWhite, "#FFFFFF"),
                                                        "red": (.mvmRed, "#D52B1E"),
                                                        "pink": (.mvmPink, "#D90368"),
                                                        "pink33": (.mvmPink33, "#F2ABCD"),
                                                        "pink66": (.mvmPink66, "#E6589B"),
                                                        "pinkShade1": (.mvmPinkShade1, "#B31C63"),
                                                        "pinkShade2": (.mvmPinkShade2, "#830842"),
                                                        "purple": (.mvmPurple, "#8C00AC"),
                                                        "purple33": (.mvmPurple33, "#D9ABE4"),
                                                        "purple66": (.mvmPurple66, "#B356C8"),
                                                        "purpleShade1": (.mvmPurpleShade1, "#6C177F"),
                                                        "purpleShade2": (.mvmPurpleShade2, "#4A0E58"),
                                                        "green": (.mvmGreen, "#008330"),
                                                        "green33": (.mvmGreen33, "#ABE4BF"),
                                                        "green66": (.mvmGreen66, "#57C880"),
                                                        "greenShade2": (.mvmGreenShade2, "#0F5B25"),
                                                        "greenInverted": (.mvmGreenInverted, "#00AC3E"),
                                                        "orange": (.mvmOrange, "#ED7000"),
                                                        "orange66": (.mvmOrange66, "#F3A157"),
                                                        "orange33": (.mvmOrange33, "#F9D0AB"),
                                                        "orangeShade1": (.mvmOrangeShade1, "#CB5F00"),
                                                        "orangeShade2": (.mvmOrangeShade2, "#984700"),
                                                        "orangeAA": (.mvmOrangeAA, "#CC4D0F"),
                                                        "blue": (.mvmBlue, "#0077B4"),
                                                        "blue33": (.mvmBlue33, "#ABD8EF"),
                                                        "blue66": (.mvmBlue66, "#57B1DF"),
                                                        "blueShade1": (.mvmBlueShade1, "#136598"),
                                                        "blueShade2": (.mvmBlueShade2, "#0B4467"),
                                                        "blueInverted": (.mvmBlueInverted, "#0088CE"),
                                                        "yellow": (.mvmYellow, "#FFBC3D"),
                                                        "coolGray1": (.mvmCoolGray1, "#F6F6F6"),
                                                        "coolGray3": (.mvmCoolGray3, "#D8DADA"),
                                                        "coolGray6": (.mvmCoolGray6, "#747676"),
                                                        "coolGray10": (.mvmCoolGray10, "#333333"),
                                                        "upGold1": (.vzupGold1, "#F9D542"),
                                                        "upGold2": (.vzupGold2, "#F4CA53"),
                                                        "upGold3": (.vzupGold3, "#CC9B2D")]
    
    //--------------------------------------------------
    // MARK: - Brand
    //--------------------------------------------------
    
    /// HEX: #000000
    public static let mvmBlack = UIColor.black
    
    /// HEX: #FFFFFF
    public static let mvmWhite = UIColor.white
    
    //--------------------------------------------------
    // MARK: - Red
    //--------------------------------------------------
    
    /// HEX: #D52B1E
    public static let mvmRed = UIColor.assetColor(named: "red")
    
    //--------------------------------------------------
    // MARK: - Pink
    //--------------------------------------------------
    
    /// HEX: #D90368
    public static let mvmPink = UIColor.assetColor(named: "pink")
    
    /// HEX: #F2ABCD
    public static let mvmPink33 = UIColor.assetColor(named: "pink33")
    
    /// HEX: #E6589B
    public static let mvmPink66 = UIColor.assetColor(named: "pink66")
    
    /// HEX: #B31C63
    public static let mvmPinkShade1 = UIColor.assetColor(named: "pinkShade1")
    
    /// HEX: #830842
    public static let mvmPinkShade2 = UIColor.assetColor(named: "pinkShade2")
    
    //--------------------------------------------------
    // MARK: - Purple
    //--------------------------------------------------
    
    /// HEX: #8C00AC
    public static let mvmPurple = UIColor.assetColor(named: "purple")
    
    /// HEX: #D9ABE4
    public static let mvmPurple33 = UIColor.assetColor(named: "purple33")
    
    /// HEX: #B356C8
    public static let mvmPurple66 = UIColor.assetColor(named: "purple66")
    
    /// HEX: #6C177F
    public static let mvmPurpleShade1 = UIColor.assetColor(named: "purpleShade1")
    
    /// HEX: #4A0E58
    public static let mvmPurpleShade2 = UIColor.assetColor(named: "purpleShade2")
    
    //--------------------------------------------------
    // MARK: - Orange
    //--------------------------------------------------
    
    /// HEX: #ED7000
    public static let mvmOrange = UIColor.assetColor(named: "orange")
    
    /// HEX: #CC4D0F
    public static let mvmOrangeAA = UIColor.assetColor(named: "orangeAA")
    
    /// HEX: #F9D0AB
    public static let mvmOrange33 = UIColor.assetColor(named: "orange33")
    
    /// HEX: #F3A157
    public static let mvmOrange66 = UIColor.assetColor(named: "orange66")
    
    /// HEX: #CB5F00
    public static let mvmOrangeShade1 = UIColor.assetColor(named: "orangeShade1")
    
    /// HEX: #984700
    public static let mvmOrangeShade2 = UIColor.assetColor(named: "orangeShade2")
    
    //--------------------------------------------------
    // MARK: - Green
    //--------------------------------------------------
    
    /// HEX: #008330
    public static let mvmGreen = UIColor.assetColor(named: "green")
    
    /// HEX: #ABE4BF
    public static let mvmGreen33 = UIColor.assetColor(named: "green33")
    
    /// HEX: #57C880
    public static let mvmGreen66 = UIColor.assetColor(named: "green66")
    
    /// HEX: #0F5B25
    public static let mvmGreenShade2 = UIColor.assetColor(named: "greenShade2")
    
    /// HEX: #00AC3E
    public static let mvmGreenInverted = UIColor.assetColor(named: "greenInverted")
    
    //--------------------------------------------------
    // MARK: - Blue
    //--------------------------------------------------
    
    /// HEX: #0077B4
    public static let mvmBlue = UIColor.assetColor(named: "blue")
    
    /// HEX: #ABD8EF
    public static let mvmBlue33 = UIColor.assetColor(named: "blue33")
    
    /// HEX: #57B1DF
    public static let mvmBlue66 = UIColor.assetColor(named: "blue66")
    
    /// HEX: #136598
    public static let mvmBlueShade1 = UIColor.assetColor(named: "blueShade1")
    
    /// HEX: #0B4467
    public static let mvmBlueShade2 = UIColor.assetColor(named: "blueShade2")
    
    /// HEX: #0088CE
    public static let mvmBlueInverted = UIColor.assetColor(named: "blueInverted")
    
    //--------------------------------------------------
    // MARK: - Yellow
    //--------------------------------------------------
    
    /// HEX: #FFBC3D
    public static let mvmYellow = UIColor.assetColor(named: "yellow")
    
    //--------------------------------------------------
    // MARK: - Gray
    //--------------------------------------------------
    
    /// HEX: #F6F6F6
    public static let mvmCoolGray1 = UIColor.assetColor(named: "coolGray1")
    
    /// HEX: #D8DADA
    public static let mvmCoolGray3 = UIColor.assetColor(named: "coolGray3")
    
    /// HEX: #747676
    @objc public static let mvmCoolGray6 = UIColor.assetColor(named: "coolGray6")
    
    /// HEX: #333333
    public static let mvmCoolGray10 = UIColor.assetColor(named: "coolGray10")
    
    //--------------------------------------------------
    // MARK: - VZ UP Brand
    //--------------------------------------------------
    
    /// HEX: #F9D542
    public static let vzupGold1 = UIColor.assetColor(named: "upGold1")
    
    /// HEX: #F4CA53
    public static let vzupGold2 = UIColor.assetColor(named: "upGold2")
    
    /// HEX: #CC9B2D
    public static let vzupGold3 = UIColor.assetColor(named: "upGold3")
    
    //--------------------------------------------------
    // MARK: - Functions
    //--------------------------------------------------
    
    public static func assetColor(named name: String) -> UIColor {
        return UIColor(named: name, in: MVMCoreUIUtility.bundleForMVMCoreUI(), compatibleWith: nil)!
    }
    
    /// Convenience to get a grayscale UIColor where the same value is used for red, green, and blue.
    public class func grayscale(rgb: Int, alpha: CGFloat = 1.0) -> UIColor {
        
        let grayscale = CGFloat(rgb) / 255.0
        return UIColor(red: grayscale, green: grayscale, blue: grayscale, alpha: alpha)
    }
    
    /// Convenience to get a UIColor.
    public class func color8Bits(red: Int, green: Int, blue: Int, alpha: CGFloat = 1.0) -> UIColor {
        
        return UIColor(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: alpha)
    }
    
    /// Convenience to get a UIColor.
    public class func color8Bits(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat = 1.0) -> UIColor {
        
        return UIColor(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: alpha)
    }
    
    /// Gets UIColor via an 8 digit hex string.
    public class func getColorBy(hex: String) -> UIColor {
        
        var hexint: UInt64 = 0
        
        let scanner = Scanner(string: hex)
        scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
        scanner.scanHexInt64(&hexint)
        
        return UIColor(red: (CGFloat((hexint & 0xFF0000) >> 16)) / 255,
                       green: (CGFloat((hexint & 0xFF00) >> 8)) / 255,
                       blue: (CGFloat(hexint & 0xFF)) / 255,
                       alpha: 1)
    }
    
    /// Gets UIColor via an 8 digit hex string. The last two being the alpha channel.
    public class func getColorWithTransparencyBy(hex: String) -> UIColor {
        
        var hexint: UInt64 = 0
        
        let scanner = Scanner(string: hex)
        scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
        scanner.scanHexInt64(&hexint)
        
        return UIColor(red: (CGFloat((hexint & 0xFF000000) >> 24)) / 255,
                       green: (CGFloat((hexint & 0xFF0000) >> 16)) / 255,
                       blue: (CGFloat((hexint & 0xFF00) >> 8)) / 255,
                       alpha: (CGFloat(hexint & 0xFF)) / 255)
    }
    
    public class func gradientColor(_ color: UIColor?) -> UIColor {
        
        var h: CGFloat = 0
        var s: CGFloat = 0
        var b: CGFloat = 0
        var a: CGFloat = 0
        
        if color?.getHue(&h, saturation: &s, brightness: &b, alpha: &a) ?? false {
            return UIColor(hue: h, saturation: max(s - 0.17, 0.0), brightness: min(b - 0.03, 1.0), alpha: a)
        }
        
        return .white
    }
    
    /// - parameter color: The UIColor intended to retrieve its hex value.
    public class func hexString(for color: UIColor) -> String? {
        
        guard let components = color.cgColor.components else { return nil }
        
        let numberOfComponents = color.cgColor.numberOfComponents
        if numberOfComponents >= 3 {
            // RGB color space
            let r = Int(CGFloat(components[0]) * 255)
            let g = Int(CGFloat(components[1]) * 255)
            let b = Int(CGFloat(components[2]) * 255)
            
            // If alpha of color is less than 1.0 then alpha hex is relevant.
            if color.cgColor.numberOfComponents == 4 && components[3] < 1.0 {
                let a = Int(CGFloat(components[3]) * 255)
                return String(format: "%02X%02X%02X%02X", r, g, b, a)
            }
            
            return String(format: "%02X%02X%02X", r, g, b)
        } else if numberOfComponents == 2 {
            // Monochromatic color space
            let value = Int(CGFloat(components[0]) * 255)
            
            // If alpha of color is less than 1.0 then alpha hex is relevant.
            if components[1] < 1.0 {
                let alpha = Int(CGFloat(components[1]) * 255)
                return String(format: "%02X%02X%02X%02X", value, value, value, alpha)
            }
            return String(format: "%02X%02X%02X", value, value, value)
        }
        
        return nil
    }
}
