<script setup lang="ts">
import {
  ClassroomComplianceAPIClient,
  type Class,
  type ClassesResponseClass,
  type Student,
  type StudentDataPayload,
} from '@/api/classroom_compliance'
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { useAuthStore } from '@/stores/auth'
import { onMounted, ref, useTemplateRef, type Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const props = defineProps<{
  classId: string
}>()
const authStore = useAuthStore()
const route = useRoute()
const router = useRouter()
const apiClient = new ClassroomComplianceAPIClient(authStore)

const cls: Ref<Class | null> = ref(null)
const student: Ref<Student | null> = ref(null)

const moveClassDialog = useTemplateRef('move-class-dialog')
const moveClassConfirmDialog = useTemplateRef('moveClassConfirmDialog')
const moveClassDialogClassChoices: Ref<ClassesResponseClass[]> = ref([])
const moveClassDialogClassSelection: Ref<ClassesResponseClass | null> = ref(null)

interface StudentFormData {
  name: string
  deskNumber: number | null
  removed: boolean
}

const formData: Ref<StudentFormData> = ref({ name: '', deskNumber: null, removed: false })

onMounted(async () => {
  if (!await loadClass()) return
  await loadStudent()
})

async function loadClass(): Promise<boolean> {
  const classIdNumber = parseInt(props.classId, 10)
  cls.value = await apiClient.getClass(classIdNumber).handleErrorsWithAlert()
  if (!cls.value) {
    await router.replace('/classroom-compliance')
    return false
  }
  return true
}

async function loadStudent() {
  const classId = cls.value?.id
  if (!classId) return
  if ('studentId' in route.query && typeof route.query.studentId === 'string') {
    const studentId = parseInt(route.query.studentId, 10)
    student.value = await apiClient.getStudent(classId, studentId).handleErrorsWithAlert()
    if (!student.value) {
      await router.replace(`/classroom-compliance/classes/${classId}`)
      return
    }
    formData.value.name = student.value.name
    formData.value.deskNumber = student.value.deskNumber
    formData.value.removed = student.value.removed
  }
}

async function submitForm() {
  const classId = parseInt(props.classId, 10)
  const data: StudentDataPayload = {
    name: formData.value.name,
    deskNumber: formData.value.deskNumber ?? 0,
    removed: formData.value.removed,
  }
  if (student.value) {
    const updatedStudent = await apiClient
      .updateStudent(classId, student.value.id, data)
      .handleErrorsWithAlert()
    if (updatedStudent) {
      await router.replace(`/classroom-compliance/classes/${classId}/students/${updatedStudent.id}`)
    }
  } else {
    const newStudent = await apiClient.createStudent(classId, data).handleErrorsWithAlert()
    if (newStudent) {
      await router.replace(`/classroom-compliance/classes/${classId}/students/${newStudent.id}`)
    }
  }
}

function resetForm() {
  if (student.value) {
    formData.value = {
      name: student.value.name,
      deskNumber: student.value.deskNumber,
      removed: student.value.removed,
    }
  } else {
    formData.value = {
      name: '',
      deskNumber: null,
      removed: false,
    }
  }
  router.back()
}

// Move-Class-Dialog actions:
async function showMoveClassDialog() {
  // Populate the list of available classes to all but the student's current class.
  const classes = await apiClient.getClasses().handleErrorsWithAlert()
  if (classes === null) return
  moveClassDialogClassChoices.value = classes.filter(c => c.id !== cls.value?.id)
  moveClassDialogClassSelection.value = null
  moveClassDialog.value?.showModal()
}

async function doMoveClass() {
  if (!cls.value || !student.value || !moveClassDialogClassSelection.value) return
  const choice = await moveClassConfirmDialog.value?.show()
  if (!choice) return
  const newClassId = moveClassDialogClassSelection.value.id
  const result = await apiClient.moveStudentToOtherClass(cls.value.id, student.value.id, newClassId)
    .handleErrorsWithAlertNoBody()
  if (result) {
    await router.replace(`/classroom-compliance/classes/${newClassId}/students/${student.value.id}`)
  }
}
</script>
<template>
  <div v-if="cls" class="centered-content">
    <h2 class="align-center">
      <span v-if="student" v-text="'Edit ' + student.name"></span>
      <span v-if="!student">Add New Student</span>
    </h2>

    <p class="align-center">In class <span v-text="cls.number + ', ' + cls.schoolYear"></span></p>

    <form @submit.prevent="submitForm" @reset.prevent="resetForm">
      <div>
        <label for="name-input">Name</label>
        <input id="name-input" type="text" v-model="formData.name" required />
        <p class="form-input-hint">
          The full name of the student, which should be unique among all students in the class.
        </p>
      </div>
      <div>
        <label for="desk-input">Desk Number</label>
        <input id="desk-input" type="number" v-model="formData.deskNumber" />
        <p class="form-input-hint">
          Set desk number to zero to remove a student's desk assignment.
        </p>
      </div>
      <div>
        <input id="removed-checkbox" type="checkbox" v-model="formData.removed" />
        <label for="removed-checkbox" style="display: inline">Removed</label>
        <p class="form-input-hint">
          Check this if the student has been removed from the class.
        </p>
      </div>
      <div class="button-bar">
        <button type="submit">Save</button>
        <button type="reset">Cancel</button>
        <button type="button" @click="showMoveClassDialog()">Move to another class</button>
      </div>
    </form>

    <!-- Dialog for moving the student to another class. -->
    <dialog id="move-class-dialog" ref="move-class-dialog" style="max-width: 500px;">
      <p>
        Select a class to move {{ student?.name }} to:
      </p>
      <select v-model="moveClassDialogClassSelection">
        <option v-for="c in moveClassDialogClassChoices" :key="c.id" v-text="'Class ' + c.number" :value="c"></option>
      </select>

      <p v-if="moveClassDialogClassSelection" class="form-input-hint">
        Will move {{ student?.name }} from class {{ cls.number }} to class {{ moveClassDialogClassSelection.number }}.
      </p>

      <p>
        Note: All current entries for {{ student?.name }} in class {{ cls.number }} will be retained; no data is lost.
        To add new entries for {{ student?.name }}, do so via their new class.
      </p>

      <div class="button-bar">
        <button type="button" id="move-class-dialog-submit-button" @click="doMoveClass()">Submit</button>
        <button type="button" id="move-class-dialog-cancel-button" @click="moveClassDialog?.close()">Cancel</button>
      </div>
    </dialog>

    <ConfirmDialog ref="moveClassConfirmDialog">
      <p>
        Are you sure that you want to move {{ student?.name }} to class {{ moveClassDialogClassSelection?.number }}?
        Their desk number will be reset. All current entries in their previous class will be retained.
      </p>
    </ConfirmDialog>
  </div>
</template>
