//
//  String-Extension.swift
//  BaiSiSMApp
//
//  Created by davidhuang on 2022/10/12.
//  Copyright © 2022 www.davidhuang.com. All rights reserved.
//

import UIKit
import SwifterSwift

// 字符串是否为空(空的标准是nil或"")
func isEmptyString(_ string: String?) -> Bool {
    if let string = string, string.count > 0 {
        return false
    }
    return true
}

extension String {
    
    // 阿拉伯数字转文字
    static func convertNumberToChineseText(_ number: Int) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "zh_CN")
        numberFormatter.numberStyle = .spellOut
        return numberFormatter.string(from: NSNumber(value: number)) ?? ""
    }
    
    static func hasQueryParameters(urlString: String) -> Bool {
        if urlString.contains("?") {
            return true
        }
        return false
    }
    
    static func randomAlphaNumericStringT(_ length: Int) -> String {
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let randomString = (0..<length).map { _ in String(letters.randomElement()!) }.reduce("", +)
        return randomString
    }
    
    /// JSONString转换为字典
    func toDictionary() -> [String: Any] {
        guard let jsonData: Data = data(using: .utf8) else { return [String: Any]() }
        if let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) {
            if let temp = dict as? [String: Any] {
                return temp
            }
        }
        return [String: Any]()
    }
    
    /// JSONString转换为数组
    func toArray() -> [Any]? {
        guard let jsonData: Data = data(using: .utf8) else { return nil }
        if let array = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) {
            if let temp = array as? [Any] {
                return temp
            }
        }
        return nil
    }
    
    // 判断字符串并返回默认值
    func defaultStringIfEmpty(detaultValue: String = "--") -> String {
        if self.isEmpty {
            return detaultValue
        }
        return self
    }
}

extension String {
    
    // MARK: - 拨打电话
    func makePhone() {
        let phone = "telprompt://" + self
        if UIApplication.shared.canOpenURL(URL(string: phone)!) == true {
            UIApplication.shared.open(URL(string: phone)!, options: [:], completionHandler: nil)
        }
    }
    
    // MARK: - 判断是否为手机号码
    func isMobile() -> Bool {
        let reg = "^1[3456789]\\d{9}$"
        let regextestmobile = NSPredicate(format: "SELF MATCHES %@", reg)
        return regextestmobile.evaluate(with: self)
    }
    
    // MARK: - 判断密码是否合法
    // 密码至少包含一个数字，一个字母，一个特殊字符
    func isPwdLegal() -> Bool {
        let reg = "^(?=.*)(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[-~!@#$%^&*:;,.=?$\\x22]).{8,20}$"
        let regextestmobile = NSPredicate(format: "SELF MATCHES %@", reg)
        return regextestmobile.evaluate(with: self)
    }
    
    // MARK: - 是否包含字符
    func isIncludeChinese() -> Bool {
        for char in self {
            if "\u{4E00}" <= char  && char <= "\u{9FA5}" {
                return true
            }
        }
        return false
    }
    
    // MARK: - 是否符合香港身份证号码
    func isHKIdentityCardNumber() -> Bool {
        let regex = #"^([A-Z]\d{6,10}(\(\w{1}\))?)|([A-Z]\d{6,10}(\（\w{1}\）)?)$/"#
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
        let isValid = predicate.evaluate(with: self)
        print(isValid ? "正确的香港身份证号码格式":"错误的香港身份证号码格式")
        return isValid
    }
    
    func phoneNumberForUI() -> String {
        let phone = self.replacingOccurrences(of: " ", with: "")
        if phone.count == 11 {
            let st1 = phone.slicing(from: 0, length: 3)
            let st2 = phone.slicing(from: 7, length: 4)
            return st1! + "****" + st2!
        }
        return self
    }
    
    var unicodeDescription: String {
        return self.stringByReplaceUnicode
    }
    
    var stringByReplaceUnicode: String {
        let jsonDict = try? JSONSerialization.jsonObject(
            with: self.data(using: String.Encoding.utf8, allowLossyConversion: true)!,
            options: JSONSerialization.ReadingOptions.mutableLeaves)
        
        let jsonData = try? JSONSerialization.data(withJSONObject: jsonDict as Any, options: .prettyPrinted)
        let string_r = String(data: jsonData!, encoding: String.Encoding.utf8)
        return string_r ?? self
    }
    
    // 时间戳转Date
    func stringConvertDate(dateFormat: String="yyyy-MM-dd HH:mm:ss") -> Date {
        let timeZone = TimeZone.init(identifier: "UTC") // 这是重点
        let dateFormatter = DateFormatter.init()
        dateFormatter.timeZone = timeZone
        dateFormatter.dateFormat = dateFormat
        let date = dateFormatter.date(from: self)
        return date!
    }
    
    // 时间戳转Date
    func convertDate(dateFormat: String="yyyy-MM-dd HH:mm:ss") -> Date {
        let dateFormatter = DateFormatter.init()
        dateFormatter.dateFormat = dateFormat
        let date = dateFormatter.date(from: self) ?? Date()
        return date
    }
    
    // 时间戳转 DateString
    func timeStampToString() -> String {
        guard let timeStamp = self.cgFloat() else {
            return "--"
        }
        
        // 时间戳为毫秒级要 ／ 1000， 秒就不用除1000，参数带没带000
        let timeSta: TimeInterval = TimeInterval(timeStamp)
        let date = NSDate(timeIntervalSince1970: timeSta)
        let dateformatter = DateFormatter()
        dateformatter.dateFormat="yyyy-MM-dd HH:mm:ss"
        return dateformatter.string(from: date as Date)
    }
    
    func toTimeString() -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd" // 设置输入的日期格式
        if let date = formatter.date(from: self) {
            let newformatter = DateFormatter()
            newformatter.dateFormat = "yyyy-MM-dd" // 设置输出的日期格式
            let formatterDateString = newformatter.string(from: date)
            return formatterDateString
        } else {
            return ""
        }
    }
}

// MARK: - 正则获取http
extension String {
    
    // 获取http链接字符串的参数
    public var urlParameters: [String: String] {
        guard let url = URL(string: self) else {
            return [:]
        }
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
              let queryItems = components.queryItems else { return [:] }
        return queryItems.reduce(into: [String: String]()) { (result, item) in
            result[item.name] = item.value
        }
    }
    
    /// 获取http链接字符串的range
    public func getHttpRangeOfString() -> [NSTextCheckingResult]? {
        let regulaStr = "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
        do {
            let regex = try NSRegularExpression(pattern: regulaStr, options: .caseInsensitive)
            let arrayOfAllMatches = regex.matches(in: self, options: NSRegularExpression.MatchingOptions.init(rawValue: 0), range: NSRange(location: 0, length: self.count))
            return arrayOfAllMatches
        } catch {
            return nil
        }
    }
    
}

extension String {
    /// 指定关键词高亮
    /// - Parameter keyWords: 关键词
    /// - Parameter color: 高亮颜色
    func highlighted(keyWords: String?, highlightColor color: UIColor, highlightFont: UIFont? = nil, paragraph: NSMutableParagraphStyle? = nil, normalFont: UIFont? = nil) -> NSAttributedString {
        let string: String = self
        var normalAttribute: [NSAttributedString.Key: Any] = [:]
        if let paragraph = paragraph {
            normalAttribute[.paragraphStyle] = paragraph
        }
        if let normalFont = normalFont {
            normalAttribute[.font] = normalFont
        }
        let attributeString = normalAttribute.count > 0 ? NSMutableAttributedString(string: string, attributes: normalAttribute) : NSMutableAttributedString(string: string)
        guard let keyWords = keyWords else { return attributeString }
        var attribute: [NSAttributedString.Key: Any] = [.foregroundColor: color]
        // 需要改变的文本
        if let font = highlightFont {
            attribute[.font] = font
        }
        let ranges = ranges(of: keyWords, options: .caseInsensitive)
        for range in ranges where range.location + range.length <= string.count {
            attributeString.addAttributes(attribute, range: range)
        }
        return attributeString
    }
    
    /// 查找字符串中子字符串的NSRange
    /// - Parameters:
    ///   - substring: 子字符串
    ///   - options: 匹配选项
    ///   - locale: 本地化
    /// - Returns: 子字符串的NSRange数组
    func ranges(of substring: String, options: CompareOptions = [], locale: Locale? = nil) -> [NSRange] {
        var ranges: [Range<Index>] = []
        while let range = range(of: substring, options: options, range: (ranges.last?.upperBound ?? self.startIndex)..<self.endIndex, locale: locale) {
            ranges.append(range)
        }
        // [range]转换为[NSRange]返回
        return ranges.compactMap({NSRange($0, in: self)})
    }
    
    /// range转换为NSRange
    func toNSRange(from range: Range<String.Index>) -> NSRange {
        return NSRange(range, in: self)
    }
}

extension String {
    public func isYHEmpty() -> Bool {
        let realStr = self.getRealString()
        return realStr.count <= 0
    }
    
    public func getRealString() -> String {
        if self.count <= 0 { return "" }
        // 去除两端连续空格
        var targetStr = self.trimmingCharacters(in: .whitespaces)
        // 去除所有换行符
        targetStr = targetStr.replacingOccurrences(of: "\n", with: "")
        return targetStr
    }
    
    var isYHValidEmail: Bool {
        // 更简单 不严格
//        let regex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        let regex = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"
        return range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil
    }
    
    /// 字符串 生成二维码
    func generateQRCode() -> UIImage? {
        // 方法一
//        guard let data = self.data(using: .ascii, allowLossyConversion: false) else {
//            return nil
//        }
//
//        let filter = CIFilter(name: "CIQRCodeGenerator")
//        filter?.setValue(data, forKey: "inputMessage")
//
//        guard let outputImage = filter?.outputImage else {
//            return nil
//        }
//
//        let context = CIContext()
//        if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
//            return UIImage(cgImage: cgImage)
//        }
//
//        return nil
        
        // 方法二  保存图片的时候有问题
//        let data = self.data(using: String.Encoding.ascii)
//        let filter = CIFilter(name: "CIQRCodeGenerator")
//        filter?.setValue(data, forKey: "inputMessage")
//        filter?.setValue("H", forKey: "inputCorrectionLevel") // 设置二维码的容错率
//        
//        // 获取生成的二维码CIImage
//        guard let outputImage = filter?.outputImage else { return nil }
//        
//        // 将CIImage转换为UIImage
//        let scaleX = 5.0
//        let scaleY = 5.0
//        let transformedImage = outputImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY))
//        let qrCodeImage = UIImage(ciImage: transformedImage)
//        
//        return qrCodeImage
        
        // 方法三
        let data = self.data(using: String.Encoding.ascii)
        if let filter = CIFilter(name: "CIQRCodeGenerator") {
            filter.setValue(data, forKey: "inputMessage")
            filter.setValue("H", forKey: "inputCorrectionLevel")
            
            if let output = filter.outputImage {
                let scale = 10.0 // 可以调整这个值来改变二维码的分辨率
                let transformedImage = output.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
                
                let context = CIContext(options: nil)
                if let cgImage = context.createCGImage(transformedImage, from: transformedImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
    
    // 头像使用cdn地址
    func getCdnUrl() -> String {
        var replacedString = self.replacingOccurrences(of: "prod-bucket-v1-pub.oss-cn-shenzhen.aliyuncs.com", with: "prod-cdn-pub.galaxy-immi.com")
        replacedString = replacedString.replacingOccurrences(of: "test-bucket-v1-pub.oss-cn-shenzhen.aliyuncs.com", with: "test-cdn-pub.galaxy-immi.com")
        return replacedString
    }
    
    func getPrivateUrl() -> String {
        var replacedString = self.replacingOccurrences(of: "prod-bucket-v1.oss-cn-shenzhen.aliyuncs.com", with: "prod-cdn.galaxy-immi.com")
        replacedString = replacedString.replacingOccurrences(of: "test-bucket-v1.oss-cn-shenzhen.aliyuncs.com", with: "test-cdn.galaxy-immi.com")
        replacedString = replacedString.replacingOccurrences(of: "galaxy-filecenter.oss-cn-shenzhen.aliyuncs.com", with: "cdn-oss-galaxy-filecenter.galaxy-immi.com")
        return replacedString
    }
}
