<script setup lang="ts">
import type {Gottesdienst, Mark, SimplifiedMinistrant} from "@/models/models"
import {computed} from "vue"

const props = defineProps<{
    gottesdienst: Gottesdienst
    ministranten: SimplifiedMinistrant[]
    marks: Mark[]
    editable: string[]
    currentUsername: string
}>()

const emit = defineEmits<{
    toggleMark: [gid: number, mid: number]
}>()

const isAdmin = computed(() => props.currentUsername === "admin")
const currentMini = computed(() => props.ministranten.find(m => m.username === props.currentUsername))
const showCheckbox = computed(() => !!currentMini.value && !isAdmin.value)

const relevantMarks = computed(() =>
    props.marks.filter(m => m.gid === props.gottesdienst.id && m.value !== 0)
)

const sortedMinistrants = computed(() => {
    const miniMap = new Map(props.ministranten.map(m => [m.id, m]))
    return relevantMarks.value
        .map(m => ({ministrant: miniMap.get(m.mid), mark: m}))
        .filter((entry): entry is {ministrant: SimplifiedMinistrant; mark: Mark} => !!entry.ministrant)
})

function getMark(gid: number, mid: number): Mark {
    const mark = props.marks.find(m => m.mid === mid && m.gid === gid)
    return mark ?? {gid, mid, value: 0}
}

function getIconForMark(gid: number, mid: number): string {
    const mark = getMark(gid, mid).value
    switch (mark) {
        case -1: return "remove"
        case 0: return "question_mark"
        case 1: return "close"
    }
    return ""
}

function getMarkClass(gid: number, mid: number): Record<string, boolean> {
    const mark = getMark(gid, mid).value
    return {
        minus: mark === -1,
        neutral: mark === 0,
        cross: mark === 1
    }
}

function getHintForMark(gid: number, mid: number): string {
    const mark = getMark(gid, mid).value
    switch (mark) {
        case -1: return "Ich kann nicht"
        case 0: return "Egal"
        case 1: return "Ich komme"
    }
    return ""
}

function two(s: number): string {
    return (s < 10 ? "0" : "") + s
}

function formatDay(time: number | Date): string {
    const date = new Date(time)
    return two(date.getDate()) + "." + two(date.getMonth() + 1) + "."
}

function formatTime(time: number | Date): string {
    const date = new Date(time)
    return two(date.getHours()) + ":" + two(date.getMinutes())
}

function formatWeekday(time: number | Date): string {
    const date = new Date(time)
    switch (date.getDay()) {
        case 1: return "Montag"
        case 2: return "Dienstag"
        case 3: return "Mittwoch"
        case 4: return "Donnerstag"
        case 5: return "Freitag"
        case 6: return "Samstag"
        case 0: return "Sonntag"
    }
    return ""
}

function toggleOwnMark() {
    if (!currentMini.value) return
    emit("toggleMark", props.gottesdienst.id, currentMini.value.id)
}

function getOwnMarkIcon(): string {
    if (!currentMini.value) return ""
    const mark = getMark(props.gottesdienst.id, currentMini.value.id).value
    switch (mark) {
        case -1: return "close"
        case 0: return ""
        case 1: return "check"
    }
    return ""
}

function getOwnMarkClass(): Record<string, boolean> {
    if (!currentMini.value) return {}
    const mark = getMark(props.gottesdienst.id, currentMini.value.id).value
    return {
        minus: mark === -1,
        neutral: mark === 0,
        cross: mark === 1
    }
}

function getOwnMarkHint(): string {
    if (!currentMini.value) return ""
    const mark = getMark(props.gottesdienst.id, currentMini.value.id).value
    switch (mark) {
        case -1: return "Ich kann nicht"
        case 0: return "keine Angabe"
        case 1: return "Ich komme"
    }
    return ""
}
</script>

<template>
    <div class="card">
        <div class="card-header">
            <div class="title-row">
                <button
                    v-if="showCheckbox"
                    class="own-mark"
                    :class="getOwnMarkClass()"
                    @click="toggleOwnMark"
                    :title="getOwnMarkHint()"
                >
                    <i v-if="getOwnMarkIcon()" class="icon">{{ getOwnMarkIcon() }}</i>
                </button>
                <span class="name">{{ gottesdienst.name !== "" ? gottesdienst.name : "Gottesdienst" }}</span>
            </div>
            <div class="info">
                <span class="date">am {{ formatWeekday(gottesdienst.date) }} {{ formatDay(gottesdienst.date) }}</span>
                <span class="time">um {{ formatTime(gottesdienst.date) }} Uhr</span>
                <span class="attendance">Anwesenheit: {{ formatTime(gottesdienst.attendance) }}</span>
            </div>
        </div>

        <div class="card-body" v-if="sortedMinistrants.length > 0">
            <div
                v-for="{ministrant, mark} in sortedMinistrants"
                :key="ministrant.id"
                class="ministrant-row"
                :class="getMarkClass(gottesdienst.id, ministrant.id)"
            >
                <span class="mini-name">{{ ministrant.firstname }} {{ ministrant.lastname }}</span>
                <span class="mark-badge">
                    <i class="icon">{{ getIconForMark(gottesdienst.id, ministrant.id) }}</i>
                    <span class="hint">{{ getHintForMark(gottesdienst.id, ministrant.id) }}</span>
                </span>
            </div>
        </div>
        <div class="card-body empty" v-else>
            <span class="no-marks">Keine Rückmeldungen</span>
        </div>
    </div>
</template>

<style scoped lang="less">
.card {
    background: #ffffff;
    border: 1px solid #d7d5d5;
    border-radius: 8px;
    margin-bottom: 12px;
    overflow: hidden;
}

.card-header {
    padding: 12px 16px;
    border-bottom: 1px solid #e8e8e8;

    .title-row {
        display: flex;
        align-items: center;
        gap: 16px;
        margin-bottom: 4px;

        .name {
            font-weight: 700;
            font-size: 18px;
        }
    }

    .own-mark {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 36px;
        height: 36px;
        border: 2px solid #cecece;
        border-radius: 6px;
        background: #ffffff;
        cursor: pointer;
        flex-shrink: 0;
        padding: 0;
        margin: 0;
        transition: 100ms;

        i {
            margin: 0;
        }

        &:hover {
            border-color: #919191;
        }

        &.minus {
            border-color: #690b0b;
            background: #fdd5d5;
            color: #690b0b;
        }

        &.cross {
            border-color: #045b04;
            background: #d1fcd1;
            color: #045b04;
        }

        &.neutral {
            border-color: #9f9f9f;
            background: #f0f0f0;
            color: #9f9f9f;
        }

        i {
            font-size: 20px;
            font-variation-settings: "wght" 600;
        }
    }

    .info {
        display: flex;
        flex-wrap: wrap;
        gap: 4px 16px;
        font-size: 14px;
        color: #656565;

        span {
            font-weight: 700;
        }
    }
}

.card-body {
    padding: 8px 16px;

    &.empty {
        padding: 16px;
        text-align: center;
        color: #9f9f9f;
        font-size: 14px;
    }

    .ministrant-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 8px 0;
        border-bottom: 1px solid #f0f0f0;

        &:last-child {
            border-bottom: none;
        }

        .mini-name {
            font-size: 15px;
            font-weight: 500;
        }

        .mark-badge {
            display: flex;
            align-items: center;
            gap: 6px;

            i {
                border-radius: 100%;
                padding: 2px;
                font-size: 20px;
            }

            .hint {
                font-size: 13px;
                white-space: nowrap;
            }
        }

        &.minus {
            .mark-badge {
                color: #690b0b;

                i {
                    background: #fdd5d5;
                }

                .hint {
                    color: #690b0b;
                }
            }
        }

        &.cross {
            .mark-badge {
                color: #045b04;

                i {
                    background: #d1fcd1;
                }

                .hint {
                    color: #045b04;
                }
            }
        }

        &.neutral {
            .mark-badge {
                color: #9f9f9f;

                i {
                    background: #f0f0f0;
                }

                .hint {
                    color: #9f9f9f;
                }
            }
        }
    }
}
</style>
