<script setup lang="ts">
import { useAuthStore } from '@/stores/auth'
import { computed, onMounted, ref, useTemplateRef, type Ref } from 'vue'
import EntriesTable from '@/apps/classroom_compliance/EntriesTable.vue'
import { useRouter } from 'vue-router'
import ConfirmDialog from '@/components/ConfirmDialog.vue'
import { ClassroomComplianceAPIClient, type Class, type ClassNote } from '@/api/classroom_compliance'
import ClassNoteItem from './ClassNoteItem.vue'

const props = defineProps<{
  id: string
}>()
const authStore = useAuthStore()
const router = useRouter()
const cls: Ref<Class | null> = ref(null)
const notes: Ref<ClassNote[]> = ref([])
const noteContent: Ref<string> = ref('')
const scoreExpression: Ref<string> = ref('')
const scorePeriod: Ref<string> = ref('')
const canUpdateScoreParameters = computed(() => {
  return cls.value && (
    cls.value.scoreExpression !== scoreExpression.value ||
    cls.value.scorePeriod !== scorePeriod.value
  )
})

const entriesTable = useTemplateRef('entries-table')
const deleteClassDialog = useTemplateRef('deleteClassDialog')

const apiClient = new ClassroomComplianceAPIClient(authStore)

onMounted(() => {
  loadClass()
})

function loadClass() {
  const idNumber = parseInt(props.id, 10)
  apiClient.getClass(idNumber).handleErrorsWithAlert().then(result => {
    if (result) {
      cls.value = result
      refreshNotes()
      scoreExpression.value = cls.value.scoreExpression
      scorePeriod.value = cls.value.scorePeriod
    } else {
      router.back();
    }
  })
}

async function deleteThisClass() {
  if (!cls.value || !(await deleteClassDialog.value?.show())) return
  await apiClient.deleteClass(cls.value.id).handleErrorsWithAlert()
  await router.replace('/classroom-compliance')
}

async function submitNote() {
  if (noteContent.value.trim().length < 1 || !cls.value) return
  const note = await apiClient.createClassNote(cls.value?.id, noteContent.value).handleErrorsWithAlert()
  if (note) {
    noteContent.value = ''
    const updatedNotes = await apiClient.getClassNotes(cls.value?.id).handleErrorsWithAlert()
    if (updatedNotes !== null) {
      notes.value = updatedNotes
    }
  }
}

function refreshNotes() {
  if (cls.value === null) {
    notes.value = []
    return
  }
  apiClient.getClassNotes(cls.value.id).handleErrorsWithAlert().then(notesResult => {
    if (notesResult !== null) {
      notes.value = notesResult
    } else {
      notes.value = []
    }
  })
}

async function resetStudentDesks() {
  if (!cls.value) return
  await apiClient.resetStudentDesks(cls.value.id).handleErrorsWithAlert()
  // Reload the table!
  await entriesTable.value?.loadEntries()
}

async function submitScoreParametersUpdate() {
  if (!cls.value) return
  const result = await apiClient.updateScoreParameters(
    cls.value.id,
    scoreExpression.value,
    scorePeriod.value
  ).handleErrorsWithAlert()
  if (result === null) return
  // The class was updated successfully, so update the page's values.
  cls.value = result
  scoreExpression.value = cls.value.scoreExpression
  scorePeriod.value = cls.value.scorePeriod
  // Reload the table with the updated scores.
  await entriesTable.value?.loadEntries()
}

function resetScoreParameters() {
  if (!cls.value) return
  scoreExpression.value = cls.value.scoreExpression
  scorePeriod.value = cls.value.scorePeriod
}
</script>
<template>
  <div v-if="cls">
    <h1 class="align-center" style="margin-bottom: 0;">Class <span v-text="cls.number"></span></h1>
    <p class="align-center" style="margin-top: 0; margin-bottom: 2em;">For the {{ cls.schoolYear }} school year.</p>
    <div class="button-bar align-center" style="margin-bottom: 1em;">
      <button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/edit-student`)">Add
        Student</button>
      <button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/import-students`)">Import
        Students</button>
      <button type="button" @click="resetStudentDesks">Clear Assigned Desks</button>
      <button type="button" @click="deleteThisClass">Delete this Class</button>
    </div>

    <EntriesTable :classId="cls.id" ref="entries-table" />

    <div>
      <h3 style="margin-bottom: 0.25em;">Notes</h3>
      <form @submit.prevent="submitNote">
        <textarea style="min-height: 50px; min-width: 300px;" maxlength="2000" minlength="1"
          v-model="noteContent"></textarea>
        <button style="vertical-align: top; margin-left: 0.5em;" type="submit">Add Note</button>
      </form>
      <ClassNoteItem v-for="note in notes" :key="note.id" :note="note" @noteDeleted="refreshNotes()" />
    </div>

    <div>
      <h3 style="margin-bottom: 0.25em;">Scoring</h3>
      <p style="margin-top: 0.25em; margin-bottom: 0.25em;">
        Change how scores are calculated for this class here.
      </p>
      <form @submit.prevent="submitScoreParametersUpdate">
        <div>
          <label for="score-expression-input">Expression</label>
          <textarea id="score-expression-input" v-model="scoreExpression" class="text-mono" minlength="1"
            maxlength="255" style="min-width: 500px; min-height: 50px;"></textarea>
        </div>
        <p class="form-input-hint">
          The expression to use to calculate each student's score. This should be a simple mathematical expression that
          can use the following variables:
        </p>
        <ul class="form-input-hint">
          <li><span class="score-expression-variable">phone</span> - The student's phone score, defined as the number of
            compliant days divided by total days present.</li>
          <li><span class="score-expression-variable">behavior_good</span> - The proportion of days that the student had
            good behavior.</li>
          <li><span class="score-expression-variable">behavior_mediocre</span> - The proportion of days that the student
            had mediocre behavior.</li>
          <li><span class="score-expression-variable">behavior_poor</span> - The proportion of days that the student had
            poor behavior.</li>
          <li><span class="score-expression-variable">behavior</span> - A general behavior score, where a student gets
            full points for good behavior, half-points for mediocre behavior, and no points for poor behavior.</li>
        </ul>
        <p class="form-input-hint">
          As an example, a common scoring expression might be 50% phone-compliance, and 50% behavior. The expression
          below would achieve that:
        </p>
        <p style="font-family: 'SourceCodePro', monospace; font-size: smaller;">
          0.5 * phone + 0.5 * behavior
        </p>
        <div>
          <label for="score-period-select">Period</label>
          <select v-model="scorePeriod">
            <option value="week">Weekly</option>
          </select>
        </div>
        <p class="form-input-hint">
          The period over which to calculate scores.
        </p>
        <div class="button-bar">
          <button type="submit" :disabled="!canUpdateScoreParameters">Save</button>
          <button type="button" :disabled="!canUpdateScoreParameters" @click="resetScoreParameters">Reset</button>
        </div>
      </form>
    </div>

    <!-- Confirmation dialog used for attempts at deleting this class. -->
    <ConfirmDialog ref="deleteClassDialog">
      <p>
        Are you sure you want to delete this class? All data associated with it (settings, students,
        entries, grades, etc.) will be <strong>permanently deleted</strong>, and deleted data is not
        recoverable.
      </p>
    </ConfirmDialog>
  </div>
</template>
<style scoped>
.score-expression-variable {
  font-family: 'SourceCodePro', monospace;
  font-style: normal;
  color: rgb(165, 210, 253);
}
</style>
