import Foundation

// Credentials for connecting to the PDS
struct PDSCredentials: Sendable {
    var serverURL: String
    var username: String
    var password: String
    
    init?(serverURL: String, username: String, password: String) {
        // Validate inputs
        guard !serverURL.isEmpty, !username.isEmpty, !password.isEmpty else {
            return nil
        }
        
        self.serverURL = serverURL
        self.username = username
        self.password = password
    }
}

// Shared date formatters to improve performance
extension ISO8601DateFormatter {
    static let shared = ISO8601DateFormatter()
}

// Invite code model
struct InviteCode: Identifiable, Sendable {
    var id: String
    var code: String { id } // For compatibility with the view
    var uses: [CodeUse]?
    var createdAt: Date
    var disabled: Bool
    var isDisabled: Bool { disabled } // For backwards compatibility
    
    // Returns a formatted date string for display
    var formattedDate: String {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter.string(from: createdAt)
    }
    
    // Returns the number of available uses
    var availableUses: Int {
        let usedCount = uses?.count ?? 0
        return max(0, 1 - usedCount) // Assuming default of 1 use per code
    }
}

// Invite use model
struct CodeUse: Codable, Identifiable, Sendable {
    var id: String { usedBy }
    var usedBy: String
    var usedAt: String
    
    // Parsed date for the usedAt string
    var date: Date? {
        ISO8601DateFormatter.shared.date(from: usedAt)
    }
    
    // Formatted date for display
    var formattedDate: String {
        guard let date = date else { return "Unknown date" }
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter.string(from: date)
    }
}

// User model
class PDSUser: Identifiable, Hashable, Sendable, ObservableObject {
    let id: String // DID
    let joinedAt: Date
    let avatar: URL?

    @Published var handle: String
    @Published var displayName: String
    @Published var description: String
    @Published var isActive: Bool = true
    
    // Formatted date for display
    var formattedJoinDate: String {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
        return formatter.string(from: joinedAt)
    }
    
    init(id: String, handle: String, displayName: String, description: String, joinedAt: Date, avatar: URL?, isActive: Bool = true) {
        self.id = id
        self.handle = handle
        self.displayName = displayName
        self.description = description
        self.joinedAt = joinedAt
        self.avatar = avatar
        self.isActive = isActive
    }
    
    // Add Hashable conformance
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    static func == (lhs: PDSUser, rhs: PDSUser) -> Bool {
        lhs.id == rhs.id
    }
}

// Shared DateFormatter for consistent date formatting across the app
extension DateFormatter {
    static let shared: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter
    }()
    
    static let dateOnly: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
        return formatter
    }()
}

// Auth state
enum AuthState: Sendable {
    case loggedOut
    case loggedIn
}

// View state
enum ViewTab: Sendable {
    case inviteCodes
    case userList
} 