//
//  Entry.swift
//  SpeedKeys
//
//  Created by Jose Polo Ramos on 2/27/25.
//

import Foundation

/// Represents a single keyboard shortcut entry
/// Contains all the information needed to execute an action when a shortcut is triggered
class Entry: CustomStringConvertible {
    
    // Unique identifier for this entry (format: "Q::index")
    var key: String = ""
    
    // Name of the application to open (e.g., "Safari", "Terminal")
    var app: String = ""
    
    // The keyboard shortcut that triggers this entry (e.g., "⌘⇧A")
    var shortCut: String = ""
    
    // File or folder path to open with the application
    var path: String = ""
    
    // Custom shell command to execute (if provided, overrides app/path)
    var command: String = ""
    
    /// Converts the entry into a dictionary format for persistence
    /// Used when saving to UserDefaults
    var asDictionary: [String: String] {
        return [
            "key": key,
            "app": app,
            "shortCut": shortCut,
            "path": path,
            "command": command
        ]
    }
    
    /// Updates the keyboard shortcut for this entry
    /// - Parameter short: The new shortcut string
    func setShortCut(_ short: String) {
        shortCut = short
    }
    
    /// Initializes a new Entry with the provided values
    /// - Parameters:
    ///   - app: Application name to launch
    ///   - shortCut: Keyboard shortcut string
    ///   - path: File/folder path to open
    ///   - command: Custom shell command (optional)
    ///   - key: Unique key (if nil, generates one using index)
    ///   - index: Numeric index used to generate key if not provided
    init(app: String, shortCut: String, path: String, command: String, key: String?, index: Int) {
        
        self.app = app
        self.shortCut = shortCut
        self.path = path
        self.command = command
        
        // Use provided key or generate a new one
        if let key = key {
            self.key = key
        } else {
            // Generate key in format "Q::index"
            self.key = "Q::\(index)"
        }
    }
    
    /// Determines if this entry has a custom command
    /// When true, the command is executed instead of opening an app/file
    var isCommand: Bool {
        return command.isEmpty == false
    }
    
    /// Custom string representation for debugging
    /// Shows all properties in a readable format
    public var description: String {
        return "key:\(key), app:\(app), shortCut:\(shortCut), path:\(path), command:\(command)"
    }
}

/// Equatable conformance - allows comparing entries for equality
/// Two entries are equal if they have the same key
extension Entry: Equatable {
    static func == (lhs: Entry, rhs: Entry) -> Bool {
        return lhs.key == rhs.key
    }
}

/// Hashable conformance - allows entries to be used in Sets and as Dictionary keys
/// Uses the unique key property for hashing
extension Entry: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(key)
    }
}
