//
//  TigerCenterTypes.swift
//  TigerDine
//
//  Created by Campbell on 9/2/25.
//

import Foundation

/// Struct to parse the response data from the TigerCenter API when getting the information for a dining location.
struct DiningLocationParser: Decodable {
    /// An individual "event", which is just an open period for the location.
    struct Event: Decodable {
        /// Hour exceptions for the given event.
        struct HoursException: Decodable {
            let id: Int
            let name: String
            let startTime: String
            let endTime: String
            let daysOfWeek: [String]
            let startDate: String
            let endDate: String
            let open: Bool
        }
        let startTime: String
        let endTime: String
        let daysOfWeek: [String]
        let exceptions: [HoursException]?
    }
    /// An individual "menu", which can be either a daily special item or a visitng chef. Description needs to be optional because visiting chefs have descriptions but specials do not.
    struct Menu: Decodable {
        let name: String
        let description: String?
        let category: String
    }
    /// Other basic information to read from a location's JSON that we'll need later.
    let id: Int
    let mdoId: Int
    let name: String
    let summary: String
    let description: String
    let mapsUrl: String
    let events: [Event]
    let menus: [Menu]
}

/// Struct that probably doesn't need to exist but this made parsing the list of location responses easy.
struct DiningLocationsParser: Decodable {
    let locations: [DiningLocationParser]
}

/// Enum to represent the four possible states a given location can be in.
enum OpenStatus: Codable {
    case open
    case closed
    case openingSoon
    case closingSoon
}

/// An individual open period for a location.
struct DiningTimes: Equatable, Hashable, Codable {
    var openTime: Date
    var closeTime: Date
}

/// Enum to represent the five possible states a visiting chef can be in.
enum VisitingChefStatus: Codable {
    case hereNow
    case gone
    case arrivingLater
    case arrivingSoon
    case leavingSoon
}

/// A visiting chef present at a location.
struct VisitingChef: Equatable, Hashable, Codable {
    let name: String
    let description: String
    var openTime: Date
    var closeTime: Date
    var status: VisitingChefStatus
}

/// A daily special at a location.
struct DailySpecial: Equatable, Hashable, Codable {
    let name: String
    let type: String
}

/// The IDs required to get the menu for a location from FD MealPlanner. Only present if the location appears in the map.
struct FDMPIds: Hashable, Codable {
    let locationId: Int
    let accountId: Int
}

/// The basic information about a dining location needed to display it in the app after parsing is finished.
struct DiningLocation: Identifiable, Hashable, Codable {
    let id: Int
    let mdoId: Int
    let fdmpIds: FDMPIds?
    let name: String
    let summary: String
    let desc: String
    let mapsUrl: String
    let date: Date
    let diningTimes: [DiningTimes]?
    var open: OpenStatus
    var visitingChefs: [VisitingChef]?
    let dailySpecials: [DailySpecial]?
}

/// Parser to read the occupancy data for a location.
struct DiningOccupancyParser: Decodable {
    /// Represents a per-hour occupancy rating.
    struct HourlyOccupancy: Decodable {
        let hour: Int
        let today: Int
        let today_max: Int
        let one_week_ago: Int
        let one_week_ago_max: Int
        let average: Int
    }
    let count: Int
    let location: String
    let building: String
    let mdo_id: Int
    let max_occ: Int
    let open_status: String
    let intra_loc_hours: [HourlyOccupancy]
}

/// Struct used to represent a day and its hours as strings. Type used for the hours of today and the next 6 days used in DetailView.
struct WeeklyHours: Hashable {
    let day: String
    let date: Date
    let timeStrings: [String]
}
