<script setup>
import {computed, reactive, ref} from "vue";
import Modal from "../../../../Views/Components/Modal.vue";
import ParticipantData from "./ParticipantData.vue";
import MailCompose from "./MailCompose.vue";
import {toast} from "vue3-toastify";
import {useAjax} from "../../../../../resources/js/components/ajaxHandler.js";
import {format} from "date-fns";
import AmountInput from "../../../../Views/Components/AmountInput.vue";
import FullScreenModal from "../../../../Views/Components/FullScreenModal.vue";
import DialableTelephoneNumber from "../../../../Views/Components/DialableTelephoneNumber.vue";

const props = defineProps({
    data: {
        type: Object,
        default: () => ({
            localGroups: {},
            participants: {},
            event: {},
            listType: '',
        }),
    },
});

const today = format(new Date(), "yyyy-MM-dd");

const { request } = useAjax();

const searchTerms = reactive({});
const selectedStatuses = reactive({});

const event = computed(() => props.data?.event ?? {});
const participantGroups = computed(() => props.data?.participants ?? {});
const showParticipantDetails = ref(false);
const showParticipant = ref(null);
const editMode = ref(false);

const mailCompose = ref(false);

const openCancelDialog = ref(false);
const openPartialPaymentDialogSwitch = ref(false);

defineEmits(['showParticipantDetails', 'markCocExisting', 'paymentComplete'])

function openParticipantDetails(input) {
    showParticipantDetails.value = true;
    showParticipant.value = input;
    editMode.value = false;
}

async function saveParticipant(formData) {
    if (!showParticipant.value?.identifier) {
        return;
    }
    const data = await request('/api/v1/event/participant/' + showParticipant.value.identifier + '/update', {
        method: "POST",
        body: formData,
    });

    if (data.status === 'success') {
        toast.success(data.message ?? 'Die Änderungen wurden gespichert. Die Liste wird beim nächsten Neuladen neu generiert.');

        document.getElementById('participant-' + data.participant.identifier + '-fullname').innerHTML = data.participant.fullname;
        document.getElementById('participant-' + data.participant.identifier + '-birthday').innerText = data.participant.birthday;
        document.getElementById('participant-' + data.participant.identifier + '-age').innerText = data.participant.age;
        document.getElementById('participant-' + data.participant.identifier + '-localgroup').innerText = data.participant.localgroup;
        document.getElementById('participant-' + data.participant.identifier + '-arrival').innerText = data.participant.arrival;
        document.getElementById('participant-' + data.participant.identifier + '-departure').innerText = data.participant.departure;
        document.getElementById('participant-' + data.participant.identifier + '-email_1').innerText = data.participant.email_1;
        document.getElementById('participant-' + data.participant.identifier + '-email_2').innerText = data.participant.email_2 ?? '--';
        document.getElementById('participant-' + data.participant.identifier + '-phone_1').innerText = data.participant.phone_1;
        document.getElementById('participant-' + data.participant.identifier + '-phone_2').innerText = data.participant.phone_2 ?? '--';

        if (data.cocChanged) {
            document.getElementById('participant-' + data.identifier + '-coc-status').innerText = data.coc.statusText;
            document.getElementById('participant-' + data.identifier + '-coc-action').style.display=data.coc.action;
            document.getElementById('participant-' + data.identifier + '-name').className = data.coc.class;
        }

        if (data.amountChanged) {
            document.getElementById('participant-' + data.identifier + '-payment').removeAttribute('class');
            document.getElementById('participant-' + data.identifier + '-paid').innerText = data.amount.paid;
            document.getElementById('participant-' + data.identifier + '-expected').innerText = data.amount.expected;
            document.getElementById('participant-' + data.identifier + '-actions').style.display=data.amount.actions;
            document.getElementById('participant-' + data.identifier + '-payment').className = data.amount.class;
        }





        editMode.value = false;
    } else {
        toast.error(data.message ?? 'Speichern fehlgeschlagen');
    }
}


const getGroupEntries = computed(() => {
    return Object.entries(participantGroups.value ?? {});
});

const getAgeCounts = (participants) => {
    const buckets = {
        '0-5': 0,
        '6-11': 0,
        '12-15': 0,
        '16-17': 0,
        '18-27': 0,
        '27+': 0,
    };

    (participants ?? []).forEach((participant) => {
        const age = Number(participant?.age);

        if (!Number.isFinite(age)) {
            return;
        }

        if (age >= 0 && age <= 5) {
            buckets['0-5']++;
        } else if (age <= 11) {
            buckets['6-11']++;
        } else if (age <= 15) {
            buckets['12-15']++;
        } else if (age <= 17) {
            buckets['16-17']++;
        } else if (age <= 27) {
            buckets['18-27']++;
        } else {
            buckets['27+']++;
        }
    });

    return buckets;
};

const getSearchText = (participant) => {
    return [
        participant?.firstname,
        participant?.lastname,
        participant?.nickname,
        participant?.email_1,
        participant?.email_2,
        participant?.phone_1,
        participant?.phone_2,
        participant?.local_group_string,
        participant?.participation_type_string,
        participant?.efz_status_string,
        participant?.amount_string,
    ]
        .filter(Boolean)
        .join(" ")
        .toLowerCase();
};

const getFilteredParticipants = (groupKey, participants) => {
    const searchTerm = (searchTerms[groupKey] ?? "").trim().toLowerCase();

    return (participants ?? []).filter((participant) => {
        const matchesSearch =
            !searchTerm ||
            getSearchText(participant).includes(searchTerm);


        return matchesSearch;
    });
};

const getRowClass = (participant) => {
    if (participant?.unregistered_at) {
        return "bg-gray-50 text-gray-500";
    }

    if (
        Number(participant?.amount?.amount ?? participant?.amount ?? 0) !==
        Number(participant?.amount_paid?.amount ?? participant?.amount_paid ?? 0)
    ) {
        return "bg-red-50";
    }

    return "";
};

async function paymentComplete(participant) {
    const data = await request('/api/v1/event/participant/' + participant.identifier + '/payment-complete', {
        method: "POST",
    });

    if (data.status === 'success') {
        toast.success(data.message);
        document.getElementById('participant-' + participant.identifier + '-payment').removeAttribute('class');
        document.getElementById('participant-' + participant.identifier + '-paid').innerText = participant.amountExpected.readable;
        document.getElementById('participant-' + participant.identifier + '-actions').style.display='none';
    } else {
        toast.error(data.message);

    }
}

async function markCocExisting(participant) {
    const data = await request('/api/v1/event/participant/' + participant.identifier + '/mark-coc-existing', {
        method: "POST",
    });

    if (data.status === 'success') {
        toast.success(data.message);
        document.getElementById('participant-' + participant.identifier + '-coc-status').innerText = 'Gültig';
        document.getElementById('participant-' + participant.identifier + '-coc-action').style.display='none';
        document.getElementById('participant-' + participant.identifier + '-name').removeAttribute('class');
    } else {
        toast.error(data.message);

    }
}

function openCancelParticipationDialog(participant) {
    showParticipant.value = participant;
    openCancelDialog.value = true;
}

async function execCancelParticipation() {
    const data = await request('/api/v1/event/participant/' + showParticipant.value.identifier + '/signoff', {
        method: "POST",
        body: {
            cancel_date: document.getElementById('cancel_date').value,
        },
    });

    if (data.status === 'success') {
        toast.success(data.message);

        document.getElementById('participant-' + data.identifier + '-common').style.display = 'none';
        document.getElementById('participant-' + data.identifier + '-meta').style.display = 'none';

    } else {
        toast.error(data.message);

    }
    openCancelDialog.value = false;
}

async function execResignonParticipant(participant) {
    const data = await request('/api/v1/event/participant/' + participant.identifier + '/re-signon', {
        method: "POST",
    });

    if (data.status === 'success') {
        toast.success(data.message);

        document.getElementById('participant-' + data.identifier + '-common').style.display = 'none';
        document.getElementById('participant-' + data.identifier + '-meta').style.display = 'none';

    } else {
        toast.error(data.message);

    }
    openCancelDialog.value = false;
}

function openPartialPaymentDialog(participant) {
    showParticipant.value = participant;
    openPartialPaymentDialogSwitch.value = true;
}

async function execPartialPayment() {
    const data = await request('/api/v1/event/participant/' + showParticipant.value.identifier + '/partial-payment', {
        method: "POST",
        body: {
            amount: document.getElementById('partial_payment_amount').value,
        },
    });

    if (data.status === 'success') {
        toast.success(data.message);

        document.getElementById('participant-' + data.identifier + '-payment').removeAttribute('class');
        document.getElementById('participant-' + data.identifier + '-paid').innerText = data.amount.paid;
        document.getElementById('participant-' + data.identifier + '-expected').innerText = data.amount.expected;
        document.getElementById('participant-' + data.identifier + '-actions').style.display=data.amount.actions;
        document.getElementById('participant-' + data.identifier + '-payment').className = data.amount.class;
            } else {
        toast.error(data.message);

    }

    openPartialPaymentDialogSwitch.value = false;
}

const mailToType = ref('')
const recipientIdentifier = ref('')

function mailToGroup(groupKey) {
    recipientIdentifier.value = groupKey;
    mailToType.value = props.data.listType;
    mailCompose.value = true
}

</script>

<template>
    <h2>{{ event?.name ?? "Veranstaltung" }}</h2>
    <div :key="groupKey">
        <div>
            <table class="participants-table" v-for="[groupKey, participants] in getGroupEntries">
                <thead>
                <tr>
                    <th colspan="4" style="background: linear-gradient(to bottom, #fff, #f6f7f7); font-weight: bold">
                        {{ groupKey }} ({{ participants.length }} Personen)
                    </th>
                </tr>
                <tr style="background: linear-gradient(to bottom, #fff, #f6f7f7);">
                    <th class="pl-name">Name</th>
                    <th class="pl-amount">Beitrag</th>
                    <th class="pl-email">E-Mail-Adresse</th>
                    <th class="pl-phone">Telefon</th>
                </tr>
                </thead>

                <tbody>
                <template
                    v-for="participant in getFilteredParticipants(groupKey, participants)"
                    :key="participant.id"
                >
                    <tr :class="getRowClass(participant)" :id="'participant-' + participant.identifier + '-common'">
                        <td :id="'participant-' + participant.identifier +'-name'"
                            class="pl-name"
                            :class="participant.efz_status === 'checked_invalid' ? 'efz-invalid' :
                                participant.efz_status === 'not_checked' ? 'efz-not-checked' : ''">
                            <div :id="'participant-' + participant.identifier +'-fullname'" v-html="participant.fullname" /><br />
                            Geburtsdatum: <label :id="'participant-' + participant.identifier +'-birthday'">{{ participant.birthday }}</label><br />
                            Alter: <label :id="'participant-' + participant.identifier +'-age'">{{ participant.age }}</label> Jahre<br />


                            <span>eFZ-Status: <label :id="'participant-' + participant.identifier +'-coc-status'">{{ participant.efzStatusReadable }}</label></span> &nbsp;
                            <span :id="'participant-' + participant.identifier +'-coc-action'" v-if="participant.efz_status !== 'checked_valid' && participant.efz_status !== 'not_required'" class="link" style="color: #3cb62e; font-size: 11pt;" @click="markCocExisting(participant)">Vorhanden?</span>
                        </td>

                        <td class="pl-amount" :id="'participant-' + participant.identifier +'-payment'" :class="participant.amount_left_value != 0 && !participant.unregistered ? 'not-paid' : ''">
                            Gezahlt: <label :id="'participant-' + participant.identifier + '-paid'">{{ participant?.amountPaid.readable }}</label> /<br />
                            Gesamt: <label :id="'participant-' + participant.identifier + '-expected'">{{ participant?.amountExpected.readable }}</label>
                            <br /><br />
                            <span v-if="participant.amount_left_value != 0 && !participant.unregistered" :id="'participant-' + participant.identifier + '-actions'">
                                <span class="link" style="font-size:10pt;" @click="paymentComplete(participant)">Zahlung buchen</span> &nbsp;
                                <span class="link" style="font-size:10pt;" @click="openPartialPaymentDialog(participant)">Teilzahlung buchen</span>
                            </span>
                            <br/><br/>
                            <span :id="'participant-' + participant.identifier + '-paymentmethod'"
                                  style="font-size:10pt;">
                                Zahlungsweise: <label
                                :id="'participant-' + participant.identifier + '-paymentmethod-name'">{{
                                    participant.paymentMethod ?? '—'
                                }}</label>
                            </span>
                        </td>

                        <td class="pl-email">
                            <label :id="'participant-' + participant.identifier +'-email_1'" class="block-label">{{ participant?.email_1 ?? "-" }}</label>
                            <label :id="'participant-' + participant.identifier +'-email_2'" class="block-label">{{ participant.email_2 }}</label>
                        </td>

                        <td class="pl-phone">
                            <label :id="'participant-' + participant.identifier +'-phone_1'" class="block-label">P: <DialableTelephoneNumber :number="participant?.phone_1" /></label>
                            <label :id="'participant-' + participant.identifier +'-phone_2'" class="block-label">K: <DialableTelephoneNumber :number="participant?.phone_2" /></label>
                        </td>


                    </tr>

                    <tr class="participant-meta-row"  :id="'participant-' + participant.identifier + '-meta'">
                        <td colspan="5" class="pl-meta">
                            <label :id="'participant-' + participant.identifier +'-localgroup'">
                                {{ participant?.localgroup ?? "-" }}
                            </label> |
                            <strong> Anreise: </strong>
                            <label :id="'participant-' + participant.identifier +'-arrival'">
                                {{ participant?.arrival ?? "-" }}
                            </label>|
                            <strong> Abreise: </strong>
                            <label :id="'participant-' + participant.identifier +'-departure'">
                                {{ participant?.departure ?? "-" }}
                            </label> |
                            <label v-if="!participant.unregistered">
                                <strong> Angemeldet am: </strong>{{ participant?.registerDate ?? "-" }}
                            </label>
                            <label v-else>
                                <strong> Abgemeldet am: </strong>{{ participant?.unregisteredAt ?? "-" }}
                            </label> |
                            <span class="link" @click="openParticipantDetails(participant)">Details</span> |
                            <span class="link">E-Mail senden</span> |
                            <span  @click="openCancelParticipationDialog(participant)" v-if="!participant.unregistered" class="link" style="color: #da7070;">Abmelden</span>
                            <span v-else class="link" @click="execResignonParticipant(participant)" style="color: #3cb62e;">Wieder anmelden</span>
                        </td>
                    </tr>
                </template>

                <tr class="pl-summary-row">
                    <td colspan="3" class="pl-age-summary">
                        0 - 5 Jahre: <strong>{{ getAgeCounts(participants)['0-5'] ?? 0 }}</strong> |
                        6-11 Jahre: <strong>{{ getAgeCounts(participants)['6-11'] ?? 0 }}</strong> |
                        12-15 Jahre: <strong>{{ getAgeCounts(participants)['12-15'] ?? 0 }}</strong> |
                        16 - 17 Jahre: <strong>{{ getAgeCounts(participants)['16-17'] ?? 0 }}</strong> |
                        18 - 27 Jahre: <strong>{{ getAgeCounts(participants)['18-27'] ?? 0 }}</strong> |
                        27 Jahre und älter: <strong>{{ getAgeCounts(participants)['27+'] ?? 0 }}</strong>
                    </td>
                    <td class="pl-summary-action">
                        <input type="button" class="button" @click="mailToGroup(groupKey)" value="E-Mail an Gruppe senden" />
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>

    <Modal
        :show="showParticipantDetails"
        title="Anmeldedetails ansehen"
        @close="showParticipantDetails = false;"
    >
        <ParticipantData
            @cancelParticipation="openCancelParticipationDialog"
            :participant="showParticipant"
            :editMode="editMode"
            :event="event"
            @editParticipant="editMode = true"
            @saveParticipant="saveParticipant"
            @paymentComplete="paymentComplete"
            @markCocExisting="markCocExisting"
            @closeParticipantDetails="showParticipantDetails = false" />
    </Modal>

    <Modal
        :show="openCancelDialog"
        title="Anmeldung stornieren"
        width="350px"
        @close="openCancelDialog = false"
    >
        Datum der Abmeldung:
        <input type="date" style="margin-top: 10px;" id="cancel_date" :value="today" />
        <br /><br />
        <button class="button" @click="execCancelParticipation()">Abmeldung durchführen</button>
    </Modal>

    <Modal
        :show="openPartialPaymentDialogSwitch"
        title="Teilbetragszahlung"
        width="350px"
        @close="openPartialPaymentDialogSwitch   = false"
    >
        Gesamtbetrag der Zahlung:
        <AmountInput type="text" v-model="showParticipant.amountExpected.short" style="margin-top: 10px; width: 100px !important;" id="partial_payment_amount" /> Euro /
        {{showParticipant.amountExpected.readable}} Euro
        <br /><br />
        <button class="button" @click="execPartialPayment()">Teilbetrag buchen</button>
    </Modal>

    <FullScreenModal
        :show="mailCompose"
        title="E-Mail senden"
        @close="mailCompose = false"
    >
        <MailCompose @closeComposer="mailCompose = false" :event="event" :mailToType="mailToType" :recipientIdentifier="recipientIdentifier" />
    </FullScreenModal>



</template>

<style scoped>
.participants-table {
    width: 95%;
    margin: 20px auto;
    border-collapse: collapse;
}

table {
    margin-bottom: 60px !important;
}

tr {
    vertical-align: top;
}

tr td {
    height: 80px;
    padding: 10px;
    padding-top: 20px;
    font-size: 11pt;
    line-height: 1.5;
}

tr th {
    height: 40px;
    padding-left: 10px;
    vertical-align: middle;
}

tr th:after {
    content: "";
}

/* Spaltenbreiten auf Desktop */
.pl-name   { width: 300px; }
.pl-amount { width: 275px; }
.pl-email  { width: auto; }
.pl-phone  { width: auto; }

.pl-meta {
    height: 15px !important;
    font-size: 9pt;
    background-color: #ffffff;
    border-top-style: none;
}

tr:nth-child(even) {
    background-color: #f9fafb;
    border-style: solid;
    border-width: 0 1px;
    border-color: #e5e7eb;
}

tr:nth-child(odd) {
    background-color: #ffffff;
    border-style: solid;
    border-width: 5px 1px 0 1px;
    border-color: #e5e7eb;
}

tr:first-child {
    border-width: 1px 1px 0 1px;
}

tr:last-child {
    border-width: 0 1px 1px 1px;
}

tr:last-child td {
    background: linear-gradient(to bottom, #fff, #f6f7f7); font-weight: bold;
    height: 30px;
}

.button {
    display: block;
    font-size: 10pt;
    text-decoration: none;
}

.not-paid {
    color: #ff0000; background-color: #ffe6e6;
}

.efz-invalid {
    color: #ff0000; background-color: #ffe6e6;
}

.efz-not-checked {
    color: #8D914BFF; background-color: #F4E99EFF;
}

.block-label {
    display: block;
}

/* ─── Tablet ─── */
@media (max-width: 1023px) {
    .participants-table {
        width: 100%;
    }

    .pl-name   { width: 40%; }
    .pl-amount { width: 25%; }
    .pl-email,
    .pl-phone  { width: 17.5%; }

    tr td {
        padding: 8px;
        font-size: 10pt;
    }
}

/* ─── Smartphone ─── */
@media (max-width: 639px) {
    .participants-table {
        width: 100%;
        font-size: 0.85rem;
    }

    /* Auf Smartphone werden Beitrag und E-Mail ausgeblendet,
       Name + Telefon bleiben sichtbar */
    .pl-amount,
    .pl-email {
        display: none !important;
    }

    .pl-name {
        width: 65% !important;
        display: table-cell;
        padding: 10px 8px !important;
        height: auto;
        vertical-align: top;
    }

    .pl-phone {
        width: 35% !important;
        display: table-cell;
        padding: 10px 6px !important;
        height: auto;
        vertical-align: top;
        font-size: 0.8rem;
        word-break: break-all;
    }

    .pl-phone .block-label {
        margin-bottom: 4px;
    }

    /* Header-Zeile entsprechend anpassen */
    thead tr:nth-child(2) th.pl-name  { width: 65% !important; }
    thead tr:nth-child(2) th.pl-phone { width: 35% !important; }

    /* Meta-Zeile (Adresse, Aktionen) bleibt sichtbar, aber kompakter */
    .pl-meta {
        padding: 8px !important;
        font-size: 0.78rem !important;
        line-height: 1.6;
        word-break: break-word;
    }

    /* Summary-Zeile (Altersverteilung) auf Mobile: stapeln */
    .pl-summary-row {
        display: flex !important;
        flex-direction: column;
    }

    .pl-summary-row td {
        display: block;
        width: 100% !important;
        height: auto !important;
    }

    .pl-age-summary {
        font-size: 0.78rem !important;
        line-height: 1.8;
        padding: 8px !important;
    }

    .pl-summary-action input.button {
        width: 100%;
        padding: 10px;
    }

    /* tr-Border auf Mobile angleichen */
    tr td {
        height: auto;
        padding: 10px 8px;
        padding-top: 12px;
    }
}
</style>
