import Foundation struct DeviceCodeResponse: Decodable { let code: String let expiresAt: String? let pollIntervalSeconds: Int? let linkUrl: String? let qrPayload: String? } enum PollResult { case pending case expired case alreadyLinked case linked(refreshToken: String, viewerName: String) } struct HomePayload: Decodable { let continueWatching: [MediaItem] let spotlight: [MediaItem]? let shelves: [ShelfRow] let favorites: [MediaItem]? } struct ShelfRow: Decodable, Identifiable { let id: String let title: String let name: String? let kind: String? let slug: String? let items: [MediaItem] } struct MediaItem: Codable, Identifiable, Hashable { let type: String let id: String let title: String let subtitle: String? let year: Int? let posterUrl: String? let backdropUrl: String? let logoUrl: String? let mediaFileId: String? let seriesId: String? let positionMs: Int64? let durationMs: Int64? let progressId: String? let badge: String? } struct PlayResult: Decodable { let streamUrl: String let sessionId: String? let mediaFileId: String? let defaultSubtitle: DefaultSubtitle? } struct DefaultSubtitle: Decodable { let fileId: Int? let source: String? let language: String? let fileName: String? let format: String? let contentBase64: String let label: String? } struct ViewerProfile: Decodable, Identifiable, Hashable { let id: String let name: String let avatarId: String? let isOwner: Bool? let isKids: Bool? let hasPin: Bool? } struct ProfilesPayload: Decodable { let profiles: [ViewerProfile] let activeProfileId: String? let canManage: Bool? } struct ClientMe: Decodable { struct Iptv: Decodable { let enabled: Bool? } let iptv: Iptv? let profile: ViewerProfile? let deviceId: String? var iptvEnabled: Bool { iptv?.enabled == true } } struct LinkedDevice: Decodable, Identifiable, Hashable { let id: String let name: String let platform: String? let lastSeenAt: String? let createdAt: String? let current: Bool? } struct DevicesPayload: Decodable { let devices: [LinkedDevice] } struct ApproveDeviceResult: Decodable { let ok: Bool? let deviceName: String? let platform: String? } struct MediaFileInfo: Decodable, Identifiable, Hashable { let id: String let label: String? let resolution: String? let videoCodec: String? let audioCodec: String? let hdrType: String? let nodeOnline: Bool? let nodeName: String? } struct MovieDetail: Decodable { let id: String let title: String let overview: String? let year: Int? let posterUrl: String? let backdropUrl: String? let logoUrl: String? let runtime: Int? let genres: [String]? let rating: String? let cast: [String]? let director: [String]? let mediaFiles: [MediaFileInfo]? var preferredMediaFileId: String? { mediaFiles?.first(where: { $0.nodeOnline != false })?.id ?? mediaFiles?.first?.id } } struct SeriesDetail: Decodable { let id: String let title: String let overview: String? let year: Int? let posterUrl: String? let backdropUrl: String? let logoUrl: String? let genres: [String]? let rating: String? let cast: [String]? let director: [String]? let seasons: [Season]? } struct Season: Decodable, Identifiable { var id: Int { seasonNumber } let seasonNumber: Int let episodes: [Episode]? } struct Episode: Decodable, Identifiable { let id: String let title: String? let episodeNumber: Int? let seasonNumber: Int? let overview: String? let stillUrl: String? let mediaFileId: String? let available: Bool? let runtime: Int? } struct SearchPayload: Decodable { let results: [MediaItem] } struct BrowsePayload: Decodable { let id: String? let title: String? let kind: String? let total: Int? let offset: Int? let items: [MediaItem] } struct SubtitleHit: Decodable, Identifiable, Hashable { var id: String { "\(source ?? "x")-\(fileId)" } let fileId: Int let language: String? let release: String? let fileName: String? let downloadCount: Int? let hearingImpaired: Bool? let source: String? let uploader: String? } struct SubtitleSearchResult: Decodable { let configured: Bool? let imdbId: String? let title: String? let results: [SubtitleHit] } struct FetchedSubtitle: Decodable { let fileId: Int? let source: String? let fileName: String? let format: String? let contentBase64: String } struct IptvCategory: Decodable, Identifiable, Hashable { let id: String let name: String let channelCount: Int? } struct IptvChannel: Decodable, Identifiable, Hashable { var id: Int { streamId } let streamId: Int let name: String let logoUrl: String? let number: Int? let categoryId: String? let nowTitle: String? } struct IptvPlayInfo: Decodable { let streamId: Int let name: String let logoUrl: String? let streamUrl: String let format: String? let fallbackStreamUrl: String? let fallbackFormat: String? } struct ShelfPref: Codable, Identifiable, Hashable { var id: String { shelfId } let shelfId: String let name: String let slug: String? let kind: String? var visible: Bool var sortOrder: Int } struct FavoriteToggleResult: Decodable { let favorited: Bool let items: [MediaItem]? } struct ApiErrorBody: Decodable { struct ErrorObj: Decodable { let message: String? } let error: ErrorObj? } struct PlayerTrack: Identifiable, Hashable { let id: Int32 let name: String }