// Copyright © 2015 Abhishek Banthia

import Cocoa
import Firebase

struct EmailSignupConstants {
    static let CLEmailSignupEmailProperty = "email"
    static let CLOperatingSystemVersion = "OS"
    static let CLClockerVersion = "Clocker version"
    static let CLAppFeedbackDateProperty = "date"
    static let CLAppLanguageKey = "language"
}

class FinalOnboardingViewController: NSViewController {
    @IBOutlet var titleLabel: NSTextField!
    @IBOutlet var subtitleLabel: NSTextField!
    @IBOutlet var accesoryLabel: NSTextField!
    @IBOutlet var accessoryImageView: NSImageView!
    @IBOutlet var emailTextField: NSTextField!
    @IBOutlet var localizationButton: UnderlinedButton!

    private let emailValidator = EmailTextFieldValidator()

    private var serialNumber: String? {
        let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))

        guard platformExpert > 0 else {
            return nil
        }

        guard let serialNumber = (IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String) else {
            return nil
        }

        IOObjectRelease(platformExpert)

        return serialNumber
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.stringValue = "You're all set!".localized()
        subtitleLabel.stringValue = "Thank you for the details.".localized()
        accesoryLabel.stringValue = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences.".localized()
        accessoryImageView.image = Themer.shared().menubarOnboardingImage()
        emailTextField.isHidden = true
        setupLocalizationButton()
    }

    private func setupLocalizationButton() {
        let mutableParaghStyle = NSMutableParagraphStyle()
        mutableParaghStyle.alignment = .center

        let underlineRange = NSRange(location: 42, length: 14)
        let originalText = NSMutableAttributedString(string: "Help localize Clocker in your language by clicking here!")
        originalText.addAttribute(NSAttributedString.Key.underlineStyle,
                                  value: NSNumber(value: Int8(NSUnderlineStyle.single.rawValue)),
                                  range: underlineRange)
        originalText.addAttribute(NSAttributedString.Key.foregroundColor,
                                  value: Themer.shared().mainTextColor(),
                                  range: NSRange(location: 0, length: localizationButton.attributedTitle.string.count))
        originalText.addAttribute(NSAttributedString.Key.font,
                                  value: (localizationButton?.font)!,
                                  range: NSRange(location: 0, length: localizationButton.attributedTitle.string.count))
        originalText.addAttribute(NSAttributedString.Key.paragraphStyle,
                                  value: mutableParaghStyle,
                                  range: NSRange(location: 0, length: localizationButton.attributedTitle.string.count))

        localizationButton.attributedTitle = originalText
    }

    @IBAction func localizationAction(_: Any) {
        guard let localizationURL = URL(string: AboutUsConstants.CrowdInLocalizationLink),
            let languageCode = Locale.preferredLanguages.first else { return }

        NSWorkspace.shared.open(localizationURL)

        // Log this
        let custom: [String: Any] = ["Language": languageCode]
        Logger.log(object: custom, for: "Opened Localization Link")

        guard let parentVC = parent as? OnboardingParentViewController else { return }
        parentVC.performFinalStepsBeforeFinishing()
    }

    override func viewWillAppear() {
        super.viewWillAppear()
        emailTextField.becomeFirstResponder()
    }

    private func todaysDate() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .short
        dateFormatter.timeZone = TimeZone(identifier: AppFeedbackConstants.CLCaliforniaTimezoneIdentifier)
        return dateFormatter.string(from: Date())
    }

    private func extraData() -> [String: String]? {
        guard let validEmail = emailValidator.validate(field: emailTextField) else {
            Logger.info("Not sending up email because it was invalid")
            return nil
        }

        guard let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String,
            let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String else {
            return nil
        }
        let operatingSystem = ProcessInfo.processInfo.operatingSystemVersion
        let osVersion = "\(operatingSystem.majorVersion).\(operatingSystem.minorVersion).\(operatingSystem.patchVersion)"
        let versionInfo = "Clocker \(shortVersion) (\(appVersion))"

        return [
            EmailSignupConstants.CLEmailSignupEmailProperty: validEmail,
            EmailSignupConstants.CLOperatingSystemVersion: osVersion,
            EmailSignupConstants.CLClockerVersion: versionInfo,
            EmailSignupConstants.CLAppFeedbackDateProperty: todaysDate(),
            EmailSignupConstants.CLAppLanguageKey: Locale.preferredLanguages.first ?? "en-US",
        ]
    }

    func sendUpEmailIfValid() {
        guard let identifier = serialNumber, let annotations = extraData() else {
            // Either serial number wasn't present or email wasn't added. Abort.
            return
        }

        let myRootReference = Firebase(url: "https://fiery-heat-5237.firebaseio.com/EmailSignup")
        let feedbackReference = myRootReference?.child(byAppendingPath: identifier)
        feedbackReference?.setValue(annotations)
    }
}

class EmailTextFieldValidator {
    func validate(field: NSTextField) -> String? {
        let trimmedText = field.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)

        guard let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return nil
        }

        let range = NSMakeRange(0, NSString(string: trimmedText).length)
        let allMatches = dataDetector.matches(in: trimmedText,
                                              options: [],
                                              range: range)

        if allMatches.count == 1,
            allMatches.first?.url?.absoluteString.contains("mailto:") == true {
            return trimmedText
        }
        return nil
    }
}