//
//  String+Extensions.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 01/03/2024.
//

import Foundation

// MARK: - Trimming and stuff
extension String {
    func trunc(length: Int, trailing: String = "…") -> String {
        return (self.count > length) ? self.prefix(length) + trailing : self
    }

    var trimmed: String {
        trimmingCharacters(in: .whitespacesAndNewlines)
    }
    
    func replaceCharactersFromSet(characterSet: CharacterSet, replacementString: String = "") -> String {
        components(separatedBy: characterSet).joined(separator:replacementString)
    }

    var canonicalVersion: String {
        trimmed.replaceCharactersFromSet(characterSet: .punctuationCharacters, replacementString: " ").folding(options: .diacriticInsensitive, locale: .current).lowercased()
    }
    
    var canonicalVersionWithPunctuation: String {
        trimmed.folding(options: .diacriticInsensitive, locale: .current).lowercased()
    }
    
    var removingFirstCharacter: String {
        String(dropFirst())
    }
    
    func isValidEmail() -> Bool {
        let emailRegEx = "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}$"
        let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        return emailPredicate.evaluate(with: self)
    }
    
}

// MARK: - Club Name
extension String {
    func acronym() -> String {
        let acronym = canonicalVersion.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines)
        if acronym.count > 10 {
            return concatenateFirstLetters().uppercased()
        } else {
            return acronym.uppercased()
        }
    }
    
    func concatenateFirstLetters() -> String {
        // Split the input into sentences
        let sentences = self.components(separatedBy: .whitespacesAndNewlines)
        if sentences.count == 1 {
            return String(self.prefix(10))
        }
        // Extract the first character of each sentence
        let firstLetters = sentences.compactMap { sentence -> Character? in
            let trimmedSentence = sentence.trimmingCharacters(in: .whitespacesAndNewlines)
            if trimmedSentence.count > 2 {
                if let firstCharacter = trimmedSentence.first {
                    return firstCharacter
                }
            }
            return nil
        }
        
        // Join the first letters together into a string
        let result = String(firstLetters)
        return result
    }
}

// MARK: - FFT License
extension String {
    var computedLicense: String {
        if let licenseKey {
            return self + licenseKey
        } else {
            return self
        }
    }
    
    var strippedLicense: String? {
        var dropFirst = 0
        if hasPrefix("0") {
            dropFirst = 1
        }
        if let match = self.dropFirst(dropFirst).firstMatch(of: /[0-9]{6,8}/) {
            let lic = String(self.dropFirst(dropFirst)[match.range.lowerBound..<match.range.upperBound])
            return lic
        } else {
            return nil
        }
    }
    
    var isLicenseNumber: Bool {
        if let match = self.firstMatch(of: /[0-9]{6,8}[A-Z]/) {
            let lic = String(self[match.range.lowerBound..<match.range.upperBound].dropLast(1))
            let lastLetter = String(self[match.range.lowerBound..<match.range.upperBound].suffix(1))
            
            if let lkey = lic.licenseKey {
                return lkey == lastLetter
            }
        }
        
        return false
    }
    
    var licenseKey: String? {
        if let intValue = Int(self) {
            var value = intValue
            value -= 1
            value = value % 23
            let v = UnicodeScalar("A").value
            let i = Int(v)
            if let s = UnicodeScalar(i + value) {
                var c = Character(s)
                if c >= "I" {
                    value += 1
                    if let newS = UnicodeScalar(i + value) {
                        c = Character(newS)
                    }
                }
                
                if c >= "O" {
                    value += 1
                    if let newS = UnicodeScalar(i + value) {
                        c = Character(newS)
                    }
                }
                

                if c >= "Q" {
                    value += 1
                    if let newS = UnicodeScalar(i + value) {
                        c = Character(newS)
                    }
                }
                
                return String(c)
            }
        }
        return nil
    }

    func licencesFound() -> [String] {
        let matches = self.matches(of: /[1-9][0-9]{5,7}/)
        return matches.map { String(self[$0.range]) }
    }
}

// MARK: - FFT Source Importing
extension String {
    enum RegexStatic {
        static let mobileNumber = /^0[6-7]/
        //static let mobileNumber = /^(?:(?:\+|00)33[\s.-]{0,3}(?:\(0\)[\s.-]{0,3})?|0)[1-9](?:(?:[\s.-]?\d{2}){4}|\d{2}(?:[\s.-]?\d{3}){2})$/
    }

    func isMobileNumber() -> Bool {
        firstMatch(of: RegexStatic.mobileNumber) != nil
    }

    //april 04-2024 bug with accent characters / adobe / fft
    mutating func replace(characters: [(Character, Character)]) {
        for (targetChar, replacementChar) in characters {
            self = String(self.map { $0 == targetChar ? replacementChar : $0 })
        }
    }
}

// MARK: - Player Names
extension StringProtocol {
    var firstUppercased: String { prefix(1).uppercased() + dropFirst() }
    var firstCapitalized: String { prefix(1).capitalized + dropFirst() }
}

// MARK: - todo clean up ??
extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension String {
    func createTxtFile(_ withName: String = "temp") -> URL {
        let url = FileManager.default.temporaryDirectory
                      .appendingPathComponent(withName)
                      .appendingPathExtension("txt")
        let string = self
        try? FileManager.default.removeItem(at: url)
        try? string.write(to: url, atomically: true, encoding: .utf8)
        return url
    }
}
