import Foundation

enum TenseID: String, CaseIterable, Codable, Sendable, Hashable {
    case ind_presente
    case ind_preterito
    case ind_imperfecto
    case ind_futuro
    case ind_perfecto
    case ind_pluscuamperfecto
    case ind_futuro_perfecto
    case ind_preterito_anterior
    case cond_presente
    case cond_perfecto
    case subj_presente
    case subj_imperfecto_1
    case subj_imperfecto_2
    case subj_perfecto
    case subj_pluscuamperfecto_1
    case subj_pluscuamperfecto_2
    case subj_futuro
    case subj_futuro_perfecto
    case imp_afirmativo
    case imp_negativo

    static let defaultPractice: [TenseID] = [
        .ind_presente,
        .ind_preterito,
        .ind_imperfecto,
        .ind_futuro,
    ]

    /// The 6 most essential tenses every learner should master.
    static let coreTenses: Set<TenseID> = [
        .ind_presente,
        .ind_preterito,
        .ind_imperfecto,
        .ind_futuro,
        .subj_presente,
        .imp_afirmativo,
    ]

    static let coreTenseIDs = coreTenses.map(\.rawValue)

    static let defaultPracticeIDs = defaultPractice.map(\.rawValue)
}

struct TenseInfo: Identifiable, Hashable, Sendable {
    let id: String
    let spanish: String
    let english: String
    let mood: String
    let order: Int

    var isCore: Bool {
        TenseID(rawValue: id).map { TenseID.coreTenses.contains($0) } ?? false
    }

    static let all: [TenseInfo] = [
        TenseInfo(id: TenseID.ind_presente.rawValue, spanish: "Indicativo Presente", english: "Present", mood: "Indicative", order: 0),
        TenseInfo(id: TenseID.ind_preterito.rawValue, spanish: "Indicativo Pretérito", english: "Preterite", mood: "Indicative", order: 1),
        TenseInfo(id: TenseID.ind_imperfecto.rawValue, spanish: "Indicativo Imperfecto", english: "Imperfect", mood: "Indicative", order: 2),
        TenseInfo(id: TenseID.ind_futuro.rawValue, spanish: "Indicativo Futuro", english: "Future", mood: "Indicative", order: 3),
        TenseInfo(id: TenseID.ind_perfecto.rawValue, spanish: "Indicativo Perfecto", english: "Present Perfect", mood: "Indicative", order: 4),
        TenseInfo(id: TenseID.ind_pluscuamperfecto.rawValue, spanish: "Indicativo Pluscuamperfecto", english: "Pluperfect", mood: "Indicative", order: 5),
        TenseInfo(id: TenseID.ind_futuro_perfecto.rawValue, spanish: "Indicativo Futuro Perfecto", english: "Future Perfect", mood: "Indicative", order: 6),
        TenseInfo(id: TenseID.ind_preterito_anterior.rawValue, spanish: "Indicativo Pretérito Anterior", english: "Preterite Perfect", mood: "Indicative", order: 7),
        TenseInfo(id: TenseID.cond_presente.rawValue, spanish: "Condicional Presente", english: "Conditional", mood: "Conditional", order: 8),
        TenseInfo(id: TenseID.cond_perfecto.rawValue, spanish: "Condicional Perfecto", english: "Conditional Perfect", mood: "Conditional", order: 9),
        TenseInfo(id: TenseID.subj_presente.rawValue, spanish: "Subjuntivo Presente", english: "Present Subjunctive", mood: "Subjunctive", order: 10),
        TenseInfo(id: TenseID.subj_imperfecto_1.rawValue, spanish: "Subjuntivo Imperfecto I", english: "Past Subjunctive (ra)", mood: "Subjunctive", order: 11),
        TenseInfo(id: TenseID.subj_imperfecto_2.rawValue, spanish: "Subjuntivo Imperfecto II", english: "Past Subjunctive (se)", mood: "Subjunctive", order: 12),
        TenseInfo(id: TenseID.subj_perfecto.rawValue, spanish: "Subjuntivo Perfecto", english: "Subjunctive Perfect", mood: "Subjunctive", order: 13),
        TenseInfo(id: TenseID.subj_pluscuamperfecto_1.rawValue, spanish: "Subjuntivo Pluscuamperfecto I", english: "Subjunctive Pluperfect (ra)", mood: "Subjunctive", order: 14),
        TenseInfo(id: TenseID.subj_pluscuamperfecto_2.rawValue, spanish: "Subjuntivo Pluscuamperfecto II", english: "Subjunctive Pluperfect (se)", mood: "Subjunctive", order: 15),
        TenseInfo(id: TenseID.subj_futuro.rawValue, spanish: "Subjuntivo Futuro", english: "Subjunctive Future", mood: "Subjunctive", order: 16),
        TenseInfo(id: TenseID.subj_futuro_perfecto.rawValue, spanish: "Subjuntivo Futuro Perfecto", english: "Subjunctive Future Perfect", mood: "Subjunctive", order: 17),
        TenseInfo(id: TenseID.imp_afirmativo.rawValue, spanish: "Imperativo Afirmativo", english: "Imperative", mood: "Imperative", order: 18),
        TenseInfo(id: TenseID.imp_negativo.rawValue, spanish: "Imperativo Negativo", english: "Negative Imperative", mood: "Imperative", order: 19),
    ]

    static let persons = ["yo", "tú", "él/ella/Ud.", "nosotros", "vosotros", "ellos/ellas/Uds."]

    static func byMood() -> [(String, [TenseInfo])] {
        let grouped = Dictionary(grouping: all, by: \.mood)
        return ["Indicative", "Conditional", "Subjunctive", "Imperative"].compactMap { mood in
            guard let tenses = grouped[mood] else { return nil }
            return (mood, tenses.sorted { $0.order < $1.order })
        }
    }

    static func find(_ id: String) -> TenseInfo? {
        all.first { $0.id == id }
    }
}
