<script setup lang="ts">
    import { useI18n } from "vue-i18n";
    import authState from "@/services/auth/auth-service.ts";
    import { onMounted, ref, watchEffect } from "vue";
    import { useRoute } from "vue-router";
    import type { ClassResponse } from "@/controllers/classes";
    import type { JoinRequestsResponse, StudentsResponse } from "@/controllers/students";
    import type { StudentDTO } from "@dwengo-1/common/interfaces/student";
    import UsingQueryResult from "@/components/UsingQueryResult.vue";
    import { useTeacherJoinRequestsQuery, useUpdateJoinRequestMutation } from "@/queries/teachers";
    import type { ClassJoinRequestDTO } from "@dwengo-1/common/interfaces/class-join-request";
    import { useClassDeleteStudentMutation, useClassQuery, useClassStudentsQuery } from "@/queries/classes";
    import { useCreateTeacherInvitationMutation } from "@/queries/teacher-invitations";
    import type { TeacherInvitationData } from "@dwengo-1/common/interfaces/teacher-invitation";
    import { useDisplay } from "vuetify";
    import "../../assets/common.css";

    const { t } = useI18n();

    const route = useRoute();
    const classId: string = route.params.id as string;
    const username = ref<string | undefined>(undefined);
    const isLoading = ref(false);
    const isError = ref(false);
    const errorMessage = ref<string>("");
    const usernameTeacher = ref<string | undefined>(undefined);

    // Queries used to access the backend and catch loading or errors

    // Gets the class a teacher wants to manage
    const getClass = useClassQuery(classId);
    // Get all students part of the class
    const getStudents = useClassStudentsQuery(classId);
    // Get all join requests for this class
    const joinRequestsQuery = useTeacherJoinRequestsQuery(username, classId);
    // Handle accepting or rejecting join requests
    const { mutate } = useUpdateJoinRequestMutation();
    // Handle deletion of a student from the class
    const { mutate: deleteStudentMutation } = useClassDeleteStudentMutation();
    // Handle creation of teacher invites
    const { mutate: sentInviteMutation } = useCreateTeacherInvitationMutation();

    // Load current user before rendering the page
    onMounted(async () => {
        isLoading.value = true;
        try {
            const userObject = await authState.loadUser();
            username.value = userObject!.profile.preferred_username;
        } catch (error) {
            isError.value = true;
            errorMessage.value = error instanceof Error ? error.message : String(error);
        } finally {
            isLoading.value = false;
        }
    });

    // Used to set the visibility of the dialog
    const dialog = ref(false);
    // Student selected for deletion
    const selectedStudent = ref<StudentDTO | null>(null);

    // Let the teacher verify deletion of a student
    function showPopup(s: StudentDTO): void {
        selectedStudent.value = s;
        dialog.value = true;
    }

    async function removeStudentFromclass(): Promise<void> {
        // Delete student from class
        deleteStudentMutation(
            { id: classId, username: selectedStudent.value!.username },
            {
                onSuccess: async () => {
                    dialog.value = false;
                    await getStudents.refetch();
                    showSnackbar(t("success"), "success");
                },
                onError: (e) => {
                    dialog.value = false;
                    showSnackbar(t("failed") + ": " + e.response.data.error || e.message, "error");
                },
            },
        );
    }

    function handleJoinRequest(c: ClassJoinRequestDTO, accepted: boolean): void {
        // Handle acception or rejection of a join request
        mutate(
            {
                teacherUsername: username.value!,
                studentUsername: c.requester.username,
                classId: c.class,
                accepted: accepted,
            },
            {
                onSuccess: async () => {
                    if (accepted) {
                        await joinRequestsQuery.refetch();
                        await getStudents.refetch();

                        showSnackbar(t("accepted"), "success");
                    } else {
                        await joinRequestsQuery.refetch();
                        showSnackbar(t("rejected"), "success");
                    }
                },
                onError: (e) => {
                    showSnackbar(t("failed") + ": " + e.response.data.error || e.message, "error");
                },
            },
        );
    }

    function sentInvite(): void {
        if (!usernameTeacher.value) {
            showSnackbar(t("valid-username"), "error");
            return;
        }
        const data: TeacherInvitationData = {
            sender: username.value!,
            receiver: usernameTeacher.value,
            class: classId,
        };
        sentInviteMutation(data, {
            onSuccess: () => {
                usernameTeacher.value = "";
            },
            onError: (e) => {
                console.log("error", e);
                console.log(e.response.data.error);
                showSnackbar(t("failed") + ": " + e.response.data.error || e.message, "error");
            },
        });
    }

    // Default of snackbar values
    const snackbar = ref({
        visible: false,
        message: "",
        color: "success",
    });

    // Function to show snackbar on success or failure
    function showSnackbar(message: string, color: string): void {
        snackbar.value.message = message;
        snackbar.value.color = color;
        snackbar.value.visible = true;
    }

    // Custom breakpoints
    const customBreakpoints = {
        xs: 0,
        sm: 500,
        md: 1370,
        lg: 1400,
        xl: 1600,
    };

    // Logic for small screens
    const display = useDisplay();

    // Reactive variables to hold custom logic based on breakpoints
    const isSmAndDown = ref(false);
    const isMdAndDown = ref(false);

    watchEffect(() => {
        // Custom breakpoint logic
        isSmAndDown.value = display.width.value < customBreakpoints.sm;
        isMdAndDown.value = display.width.value < customBreakpoints.md;
    });
</script>
<template>
    <main>
        <div
            class="loading-div"
            v-if="isLoading"
        >
            <v-progress-circular indeterminate></v-progress-circular>
        </div>
        <div v-if="isError">
            <v-empty-state
                icon="mdi-alert-circle-outline"
                :text="errorMessage"
                :title="t('error_title')"
            ></v-empty-state>
        </div>
        <using-query-result
            :query-result="getClass"
            v-slot="classResponse: { data: ClassResponse }"
        >
            <div>
                <h1 class="h1">{{ classResponse.data.class.displayName }}</h1>
                <using-query-result
                    :query-result="getStudents"
                    v-slot="studentsResponse: { data: StudentsResponse }"
                >
                    <v-container
                        fluid
                        class="ma-4"
                    >
                        <v-row
                            no-gutters
                            fluid
                        >
                            <v-col
                                cols="12"
                                sm="6"
                                md="6"
                            >
                                <v-table class="table">
                                    <thead>
                                        <tr>
                                            <th class="header">{{ t("students") }}</th>
                                            <th class="header"></th>
                                        </tr>
                                    </thead>

                                    <tbody v-if="studentsResponse.data.students.length">
                                        <tr
                                            v-for="s in studentsResponse.data.students as StudentDTO[]"
                                            :key="s.id"
                                        >
                                            <td>{{ s.firstName + " " + s.lastName }}</td>
                                            <td>
                                                <v-btn @click="showPopup(s)">{{ t("remove") }}</v-btn>
                                            </td>
                                        </tr>
                                    </tbody>

                                    <tbody v-else>
                                        <tr>
                                            <td
                                                colspan="2"
                                                class="empty-message"
                                            >
                                                <v-icon
                                                    icon="mdi-information-outline"
                                                    size="small"
                                                >
                                                </v-icon>
                                                {{ t("no-students-found") }}
                                            </td>
                                        </tr>
                                    </tbody>
                                </v-table>
                            </v-col>
                            <using-query-result
                                :query-result="joinRequestsQuery"
                                v-slot="joinRequests: { data: JoinRequestsResponse }"
                            >
                                <v-col
                                    cols="12"
                                    sm="6"
                                    md="6"
                                >
                                    <v-table class="table">
                                        <thead>
                                            <tr>
                                                <th class="header">{{ t("classJoinRequests") }}</th>
                                                <th class="header">{{ t("accept") + "/" + t("reject") }}</th>
                                            </tr>
                                        </thead>
                                        <tbody v-if="joinRequests.data.joinRequests.length">
                                            <tr
                                                v-for="jr in joinRequests.data.joinRequests as ClassJoinRequestDTO[]"
                                                :key="(jr.class, jr.requester, jr.status)"
                                            >
                                                <td>
                                                    {{ jr.requester.firstName + " " + jr.requester.lastName }}
                                                </td>
                                                <td>
                                                    <span v-if="!isSmAndDown && !isMdAndDown">
                                                        <v-btn
                                                            @click="handleJoinRequest(jr, true)"
                                                            class="mr-2"
                                                            color="green"
                                                        >
                                                            {{ t("accept") }}</v-btn
                                                        >

                                                        <v-btn
                                                            @click="handleJoinRequest(jr, false)"
                                                            class="mr-2"
                                                            color="red"
                                                        >
                                                            {{ t("reject") }}
                                                        </v-btn>
                                                    </span>
                                                    <span v-else>
                                                        <v-btn
                                                            @click="handleJoinRequest(jr, true)"
                                                            icon="mdi-check-circle"
                                                            class="mr-2"
                                                            color="green"
                                                            variant="text"
                                                        ></v-btn>
                                                        <v-btn
                                                            @click="handleJoinRequest(jr, false)"
                                                            icon="mdi-close-circle"
                                                            class="mr-2"
                                                            color="red"
                                                            variant="text"
                                                        ></v-btn>
                                                    </span>
                                                </td>
                                            </tr>
                                        </tbody>
                                        <tbody v-else>
                                            <tr>
                                                <td
                                                    colspan="2"
                                                    class="empty-message"
                                                >
                                                    <v-icon
                                                        icon="mdi-information-outline"
                                                        size="small"
                                                    >
                                                    </v-icon>
                                                    {{ t("no-join-requests-found") }}
                                                </td>
                                            </tr>
                                        </tbody>
                                    </v-table>
                                </v-col>
                            </using-query-result>
                        </v-row>
                    </v-container>
                </using-query-result>
            </div>
            <div>
                <div class="join">
                    <h2>{{ t("invitations") }}</h2>
                    <p>{{ t("enterUsername") }}</p>

                    <v-sheet
                        class="pa-4 sheet"
                        max-width="400"
                    >
                        <v-form @submit.prevent>
                            <v-text-field
                                :label="`${t('username')}`"
                                v-model="usernameTeacher"
                                :placeholder="`${t('username')}`"
                                variant="outlined"
                            ></v-text-field>
                            <v-btn
                                class="mt-4"
                                color="#f6faf2"
                                type="submit"
                                @click="sentInvite"
                                block
                                >{{ t("invite") }}</v-btn
                            >
                        </v-form>
                    </v-sheet>
                </div>
            </div>
            <v-dialog
                v-model="dialog"
                max-width="400px"
            >
                <v-card>
                    <v-card-title class="headline">{{ t("areusure") }}</v-card-title>

                    <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn
                            text
                            @click="dialog = false"
                        >
                            {{ t("cancel") }}
                        </v-btn>
                        <v-btn
                            text
                            @click="removeStudentFromclass"
                            >{{ t("yes") }}</v-btn
                        >
                    </v-card-actions>
                </v-card>
            </v-dialog>
            <v-snackbar
                v-model="snackbar.visible"
                :color="snackbar.color"
                timeout="3000"
            >
                {{ snackbar.message }}
            </v-snackbar>
        </using-query-result>
    </main>
</template>
<style scoped>
    h2 {
        color: #0e6942;
        font-size: 30px;
    }

    .join {
        display: flex;
        flex-direction: column;
        margin-left: 1%;
        gap: 20px;
        margin-top: 50px;
    }

    .link {
        color: #0b75bb;
        text-decoration: underline;
    }

    @media screen and (max-width: 800px) {
        .join {
            text-align: center;
            align-items: center;
            margin-left: 0;
        }

        .sheet {
            width: 100%;
        }

        main {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            margin: 5px;
        }
    }
</style>
