//
//  Extension.swift
//  Bill24OnlinePaymentSdk
//
//  Created by MacbookPro on 17/10/23.
//

import Foundation
import UIKit

extension UIColor {
    convenience init(red: Int, green: Int, blue: Int) {
        assert(red >= 0 && red <= 255, "Invalid red component")
        assert(green >= 0 && green <= 255, "Invalid green component")
        assert(blue >= 0 && blue <= 255, "Invalid blue component")
        
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }
    
    convenience init(hex: String) {
            var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
            hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")

            var rgb: UInt64 = 0
            var alpha: CGFloat = 1.0

            if hexSanitized.count == 8 { // Check if the hex string includes alpha
                let scanner = Scanner(string: hexSanitized)
                var hexValue: UInt64 = 0
                if scanner.scanHexInt64(&hexValue) {
                    rgb = (hexValue & 0xFFFFFF00) >> 8 // Extract RGB values
                    let alphaValue = hexValue & 0x000000FF // Extract alpha value
                    alpha = CGFloat(alphaValue) / 255.0 // Convert alpha to CGFloat (0-1 range)
                }
            } else if hexSanitized.count == 6 {
                if Scanner(string: hexSanitized).scanHexInt64(&rgb) {
                    // No alpha provided, use default alpha (1.0)
                }
            }

            let red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0
            let green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0
            let blue = CGFloat(rgb & 0x0000FF) / 255.0

            self.init(red: red, green: green, blue: blue, alpha: alpha)
        }

    func blended(with color: UIColor, ratio: CGFloat) -> UIColor {
        let clampedRatio = max(0, min(1, ratio))

        var red1: CGFloat = 0
        var green1: CGFloat = 0
        var blue1: CGFloat = 0
        var alpha1: CGFloat = 0
        var red2: CGFloat = 0
        var green2: CGFloat = 0
        var blue2: CGFloat = 0
        var alpha2: CGFloat = 0

        guard
            self.getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1),
            color.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)
        else {
            return self
        }

        return UIColor(
            red: red1 + (red2 - red1) * clampedRatio,
            green: green1 + (green2 - green1) * clampedRatio,
            blue: blue1 + (blue2 - blue1) * clampedRatio,
            alpha: alpha1 + (alpha2 - alpha1) * clampedRatio
        )
    }
}

extension UIImageView {
    func loadImage(from urlString: String?, placeholder: UIImage? = nil, completion: ((Bool) -> Void)? = nil) {
        guard let urlString = urlString, let url = URL(string: urlString), !urlString.isEmpty else {
            self.image = placeholder
            completion?(false)
            return
        }
        
        URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            guard let data = data, error == nil, let image = UIImage(data: data) else {
                DispatchQueue.main.async {
                    self?.image = placeholder
                    completion?(false)
                }
                return
            }
            
            DispatchQueue.main.async {
                self?.image = image
                completion?(true)
            }
        }.resume()
    }
    
    func loadQRImage(from data: Data?) {
        if let qrCodeImage = generateQRCode(from: data) {
            self.image = qrCodeImage
        }
    }
    
    func generateQRCode(from data: Data?) -> UIImage? {
        guard let data = data else { return nil }
        
        let filter = CIFilter(name: "CIQRCodeGenerator")
        filter?.setValue(data, forKey: "inputMessage")
        
        let transform = CGAffineTransform(scaleX: 10, y: 10)  // Adjust the scale as needed
        if let output = filter?.outputImage?.transformed(by: transform) {
            return UIImage(ciImage: output)
        }
        
        return nil
    }
}

extension UIFont {
    static func preferredFont(withNames fontNames: [String], size: CGFloat, bundle: Bundle) -> UIFont {
        for fontName in fontNames {
            if let fontURL = bundle.url(forResource: fontName, withExtension: "ttf"),
               let fontDataProvider = CGDataProvider(url: fontURL as CFURL),
               let font = CGFont(fontDataProvider) {
                
                if let uiFont = UIFont(name: font as! String, size: size) {
                    return uiFont
                }
            }
        }
        
        // If none of the specified fonts are available, use the system font
        return UIFont.systemFont(ofSize: size)
    }
}

extension UIView {
    func addCardShadow(cornerRadius: CGFloat, shadowColor: UIColor = .black, shadowOpacity: Float = 0.1, shadowOffsetY: CGFloat = 3, shadowBlur: CGFloat = 13) {
        self.layer.shadowColor = shadowColor.cgColor
        self.layer.shadowOpacity = shadowOpacity
        self.layer.shadowOffset = CGSize(width: 0, height: shadowOffsetY)
        self.layer.shadowRadius = shadowBlur
        self.layer.cornerRadius = cornerRadius
        self.layer.masksToBounds = false
        self.clipsToBounds = false
        // Add shadow path if bounds are known
        if self.bounds.width > 0 {
            self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: cornerRadius).cgPath
        }
    }

    func setBorder(color: UIColor, width: CGFloat, cornerRadius: CGFloat) {
        self.layer.borderColor = color.cgColor
        self.layer.borderWidth = width
        self.layer.cornerRadius = cornerRadius
        // NOTE: masksToBounds = true clips shadows. 
        // We set it to false here to allow this view to have shadows elsewhere if needed.
        // As long as the background is set on the layer, cornerRadius will clip it even with masksToBounds = false.
        self.layer.masksToBounds = false
    }

    func roundCorners(cornerRadius: CGFloat) {
        self.layer.cornerRadius = cornerRadius
        self.layer.masksToBounds = true
    }

    func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        let maskPath = UIBezierPath(
            roundedRect: bounds,
            byRoundingCorners: corners,
            cornerRadii: CGSize(width: radius, height: radius)
        )
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = maskPath.cgPath
        layer.mask = maskLayer
    }

    func saveAsImage() -> UIImage {
           let renderer = UIGraphicsImageRenderer(bounds: bounds)
           return renderer.image { rendererContext in
               layer.render(in: rendererContext.cgContext)
           }
       }
    
    
}
