package de.tsschulz.tt_tagebuch.shared.api

import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchDto
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchScope

object ScheduleLogic {

    fun sortClubTeams(teams: List<ClubTeamDto>): List<ClubTeamDto> =
        teams.sortedWith(compareBy({ it.league?.name ?: "" }, { it.name }))

    fun sortMatches(matches: List<ScheduleMatchDto>): List<ScheduleMatchDto> =
        matches.sortedWith(
            compareBy(
                { it.date ?: "" },
                { it.time ?: "" },
                { it.homeTeam?.name ?: "" },
                { it.guestTeam?.name ?: "" },
            ),
        )

    fun mergeUniqueMatches(a: List<ScheduleMatchDto>, b: List<ScheduleMatchDto>): List<ScheduleMatchDto> {
        val seen = LinkedHashSet<Int>()
        val out = ArrayList<ScheduleMatchDto>(a.size + b.size)
        for (m in a + b) {
            if (seen.add(m.id)) out.add(m)
        }
        return out
    }

    fun leagueTeamNames(matches: List<ScheduleMatchDto>): List<String> {
        val names = LinkedHashSet<String>()
        for (m in matches) {
            m.homeTeam?.name?.takeIf { it.isNotBlank() }?.let(names::add)
            m.guestTeam?.name?.takeIf { it.isNotBlank() }?.let(names::add)
        }
        return names.sorted()
    }

    fun filterAdultLeagues(matches: List<ScheduleMatchDto>): List<ScheduleMatchDto> {
        val youth = Regex("""[JM]\d|jugend""", RegexOption.IGNORE_CASE)
        return matches.filter { m ->
            val leagueName = m.leagueDetails?.name ?: ""
            !youth.containsMatchIn(leagueName)
        }
    }

    /**
     * @param ownTeamName Name des gewählten Vereins-Teams (ClubTeam), wie im Web `selectedTeam.name`.
     */
    fun applyTeamMatchScope(
        ownMatches: List<ScheduleMatchDto>,
        allMatches: List<ScheduleMatchDto>,
        scope: ScheduleMatchScope,
        ownTeamName: String,
        otherTeamName: String,
    ): List<ScheduleMatchDto> {
        val combined = sortMatches(mergeUniqueMatches(allMatches, ownMatches))
        return when (scope) {
            ScheduleMatchScope.All -> combined
            ScheduleMatchScope.Other -> {
                if (otherTeamName.isBlank()) emptyList()
                else combined.filter { m ->
                    m.homeTeam?.name == otherTeamName || m.guestTeam?.name == otherTeamName
                }
            }
            ScheduleMatchScope.Own ->
                if (ownMatches.isNotEmpty()) sortMatches(ownMatches)
                else combined.filter { m ->
                    m.homeTeam?.name == ownTeamName || m.guestTeam?.name == ownTeamName
                }
        }
    }

    fun teamsWithLeague(teams: List<ClubTeamDto>): List<ClubTeamDto> =
        teams.filter { it.league != null && (it.league?.id ?: 0) > 0 }
}
