<script setup lang="ts">
import BaseFormSelect from '@/components/base/BaseFormSelect.vue'
import BaseFormTextField from '@/components/base/BaseFormTextField.vue'
import ConfirmDialog from '@/components/maint/CommonConfirmDialog.vue'
import DetailNavigation from '@/components/maint/master-detail/DetailNavigation.vue'
import DetailSidePanel from '@/components/maint/master-detail/DetailSidePanel.vue'
import MasterFileFormFields from '@/components/maint/MasterFileFormFields.vue'
import MntDialogCard from '@/components/maint/MntDialogCard.vue'
import MntRecordNavToolbar from '@/components/maint/MntRecordNavToolbar.vue'
import MaintShell from '@/components/maint/MaintShell.vue'
import SectionDataTable from '@/components/sections/SectionDataTable.vue'
import { useMasterDetailAMaintenancePage } from '@/composables/page-drivers/useMasterDetailAMaintenancePage'

const {
  confirmSave, currentPage, departments, detailForm, flow, formState,
  gradeOptions, itemsPerPage, masterDetailEvents, masterDetailProps,
  openAddDialog, openEditDialog, openViewDialog, pageCount, pageModel,
  pageSummary, requestSaveConfirmation, resetSearch, scrollToField,
  search, searchPanelOpen, snackbarVisible, statuses, students, tableHeaders,
} = useMasterDetailAMaintenancePage()
</script>

<template>
  <MaintShell
    :search-panel-open="searchPanelOpen"
    :title="pageModel.title"
    @toggle-search="searchPanelOpen = !searchPanelOpen"
    @create="openAddDialog"
  >
    <template #search-fields>
      <v-col cols="12" md="2">
        <BaseFormTextField
          id="search-student-id"
          v-model="search.studentId"
          label="學號"
          :label-char-count="2"
          name="searchStudentId"
          placeholder="例如：S2024001"
        />
      </v-col>
      <v-col cols="12" md="2">
        <BaseFormTextField
          id="search-name"
          v-model="search.name"
          label="姓名"
          :label-char-count="2"
          name="searchName"
          placeholder="例如：王小明"
        />
      </v-col>
      <v-col cols="12" md="2">
        <BaseFormSelect
          id="search-department"
          v-model="search.department"
          label="系所"
          :label-char-count="2"
          :items="departments"
          name="searchDepartment"
        />
      </v-col>
      <v-col cols="12" md="2">
        <BaseFormSelect
          id="search-grade"
          v-model="search.grade"
          label="年級"
          :label-char-count="2"
          item-title="title"
          item-value="value"
          :items="gradeOptions"
          name="searchGrade"
        />
      </v-col>
      <v-col cols="12" md="2">
        <BaseFormSelect
          id="search-status"
          v-model="search.status"
          label="狀態"
          :label-char-count="2"
          :items="statuses"
          name="searchStatus"
        />
      </v-col>
      <v-col class="d-flex justify-end align-end flex-grow-1 ga-2" cols="12" md="auto">
        <v-btn variant="text" @click="resetSearch">清除</v-btn>
        <v-btn color="primary" disabled variant="tonal">查詢</v-btn>
      </v-col>
    </template>
    <template #table>
      <SectionDataTable
        :current-page="currentPage"
        :grade-label="formState.gradeLabel"
        :headers="tableHeaders"
        :items="students"
        :items-per-page="itemsPerPage"
        :page-count="pageCount"
        :page-summary="pageSummary"
        :row-props="formState.rowProps"
        :status-color="formState.statusColor"
        @delete="flow.requestDeleteConfirmation($event)"
        @edit="openEditDialog($event)"
        @update:current-page="currentPage = $event"
        @view="openViewDialog($event)"
      />
    </template>
  </MaintShell>

  <teleport to="body">
    <v-overlay
      class="dialog-overlay"
      :close-on-content-click="false"
      :model-value="masterDetailProps.dialogVisible"
      scrim="rgba(0, 0, 0, 0.45)"
      scroll-strategy="block"
      @update:model-value="flow.handleDialogVisibility($event)"
    >
      <div class="dialog-panel" :class="{ 'is-mobile': masterDetailProps.isMobile }">
        <div
          v-if="!masterDetailProps.isMobile || masterDetailProps.activeMobilePanel === 'detail'"
          class="detail-panel-wrapper"
          :class="{ 'is-active': !!masterDetailProps.selectedSemesterId, 'is-mobile': masterDetailProps.isMobile }"
        >
          <DetailSidePanel
            v-model:detail-form="detailForm"
            :is-detail-editing="masterDetailProps.isDetailEditing"
            :is-mobile="masterDetailProps.isMobile"
            :is-view-mode="masterDetailProps.isViewMode"
            :selected-semester="masterDetailProps.selectedSemester"
            v-on="masterDetailEvents"
          />
        </div>

        <MntDialogCard
          v-if="!masterDetailProps.isMobile || masterDetailProps.activeMobilePanel === 'master'"
          :dialog-subtitle="masterDetailProps.dialogSubtitle"
          :dialog-title="masterDetailProps.dialogTitle"
          :is-edit-mode="masterDetailProps.isEditMode"
          :is-view-mode="masterDetailProps.isViewMode"
          :width="masterDetailProps.isMobile ? '100%' : 760"
        >
          <template #toolbar>
            <MntRecordNavToolbar
              :has-next-record="masterDetailProps.hasNextRecord"
              :has-prev-record="masterDetailProps.hasPrevRecord"
              :is-edit-mode="masterDetailProps.isEditMode"
              :is-view-mode="masterDetailProps.isViewMode"
              :mobile="masterDetailProps.isMobile"
              v-on="masterDetailEvents"
            />
          </template>
          <template #content>
            <v-alert
              v-if="masterDetailProps.errorSummary.length > 0 && !masterDetailProps.isLoading"
              class="mb-4"
              type="error"
              variant="tonal"
            >
              <div class="text-subtitle-2 mb-2">請先修正以下問題</div>
              <div class="d-flex flex-column ga-1">
                <v-btn
                  v-for="error in masterDetailProps.errorSummary"
                  :key="error.field"
                  color="error"
                  size="small"
                  variant="text"
                  @click="scrollToField(error.field)"
                >
                  {{ error.message }}
                </v-btn>
              </div>
            </v-alert>

            <v-skeleton-loader
              v-if="masterDetailProps.isLoading"
              class="mt-4"
              type="subtitle,paragraph"
              width="100%"
            />

            <v-form
              v-else
              :class="{ 'form-readonly': masterDetailProps.isFormReadonly }"
              @submit.prevent="requestSaveConfirmation()"
            >
              <MasterFileFormFields
                :departments="masterDetailProps.departments"
                :enroll-years="masterDetailProps.enrollYears"
                :field-errors="masterDetailProps.fieldErrors"
                :form="formState.form.value"
                :grade-options="masterDetailProps.gradeOptions"
                :is-form-locked="masterDetailProps.isFormLocked"
                :is-form-readonly="masterDetailProps.isFormReadonly"
                :statuses="masterDetailProps.statuses"
                v-on="masterDetailEvents"
              />

              <v-divider />

              <DetailNavigation
                :is-mobile="masterDetailProps.isMobile"
                :is-view-mode="masterDetailProps.isViewMode"
                :selected-semester-id="masterDetailProps.selectedSemesterId"
                :semesters="masterDetailProps.semesters"
                v-on="masterDetailEvents"
              />
            </v-form>
          </template>
          <template #actions>
            <template v-if="masterDetailProps.isMobile">
              <v-btn :disabled="masterDetailProps.isSaving" variant="text" @click="flow.requestCloseDialog()">取消</v-btn>
              <v-btn
                v-if="masterDetailProps.isEditMode"
                color="error"
                :disabled="masterDetailProps.isSaving"
                variant="tonal"
                @click="flow.requestDeleteCurrent()"
              >
                刪除
              </v-btn>
              <v-btn
                v-if="!masterDetailProps.isViewMode"
                color="primary"
                :disabled="!masterDetailProps.isDirty || masterDetailProps.isLoading"
                :loading="masterDetailProps.isSaving"
                variant="flat"
                @click="requestSaveConfirmation()"
              >
                儲存
              </v-btn>
              <v-btn v-else color="primary" variant="flat" @click="flow.requestCloseDialog()">關閉</v-btn>
            </template>
            <template v-else>
              <v-spacer />
              <v-btn :disabled="masterDetailProps.isSaving" variant="text" @click="flow.requestCloseDialog()">取消</v-btn>
              <v-btn
                v-if="masterDetailProps.isEditMode"
                color="error"
                :disabled="masterDetailProps.isSaving"
                variant="tonal"
                @click="flow.requestDeleteCurrent()"
              >
                刪除
              </v-btn>
              <v-btn
                v-if="!masterDetailProps.isViewMode"
                color="primary"
                :disabled="!masterDetailProps.isDirty || masterDetailProps.isLoading"
                :loading="masterDetailProps.isSaving"
                variant="flat"
                @click="requestSaveConfirmation()"
              >
                儲存
              </v-btn>
              <v-btn v-else color="primary" variant="flat" @click="flow.requestCloseDialog()">關閉</v-btn>
            </template>
          </template>
        </MntDialogCard>
      </div>
    </v-overlay>
  </teleport>

  <ConfirmDialog
    :model-value="masterDetailProps.confirmCloseVisible"
    confirm-color="error"
    confirm-text="關閉不儲存"
    message="目前有尚未儲存的內容，確定要關閉嗎？"
    title="未儲存變更"
    @confirm="flow.confirmClose()"
    @update:model-value="flow.confirmCloseVisible.value = $event"
  />

  <ConfirmDialog
    :model-value="masterDetailProps.confirmSaveVisible"
    :confirm-loading="masterDetailProps.isSaving"
    confirm-text="確認儲存"
    max-width="520"
    title="確認儲存變更"
    @confirm="confirmSave()"
    @update:model-value="flow.confirmSaveVisible.value = $event"
  >
    <div v-if="masterDetailProps.saveSummary.length > 0" class="d-flex flex-column ga-2">
      <div v-for="item in masterDetailProps.saveSummary" :key="item.label" class="d-flex flex-column">
        <div class="text-caption text-medium-emphasis">{{ item.label }}</div>
        <div v-if="item.before !== null" class="text-body-2">
          <span class="text-medium-emphasis">原：</span>
          <span :class="{ 'text-medium-emphasis': item.before === '—' }">
            {{ item.before }}
          </span>
        </div>
        <div class="text-body-2">
          <span class="text-medium-emphasis">新：</span>
          <span :class="{ 'text-medium-emphasis': item.after === '—' }">
            {{ item.after }}
          </span>
        </div>
      </div>
    </div>
    <div v-else class="text-body-2">目前沒有可儲存的變更。</div>
  </ConfirmDialog>

  <ConfirmDialog
    :model-value="masterDetailProps.confirmDeleteVisible"
    confirm-color="error"
    confirm-text="確定刪除"
    :message="`確定要刪除 ${masterDetailProps.pendingDeleteLabel} 嗎？此操作無法復原。`"
    title="確認刪除"
    @confirm="flow.confirmDelete()"
    @update:model-value="flow.confirmDeleteVisible.value = $event"
  />

  <ConfirmDialog
    :model-value="masterDetailProps.confirmSwitchVisible"
    confirm-text="確定切換"
    max-width="480"
    message="目前有尚未儲存的內容，切換為檢視模式將會捨棄變更，確定要切換嗎？"
    title="未儲存變更"
    @confirm="flow.confirmSwitch()"
    @update:model-value="flow.confirmSwitchVisible.value = $event"
  />

  <ConfirmDialog
    :model-value="masterDetailProps.confirmNavigateVisible"
    confirm-text="確定切換"
    max-width="480"
    message="目前有尚未儲存的內容，切換到其他資料將會捨棄變更，確定要切換嗎？"
    title="未儲存變更"
    @confirm="flow.confirmNavigate()"
    @update:model-value="flow.confirmNavigateVisible.value = $event"
  />

  <v-snackbar v-model="snackbarVisible" color="success" location="bottom right" :timeout="2200">
    儲存成功
  </v-snackbar>
</template>

<style scoped>
.dialog-overlay :deep(.v-overlay__content) {
  height: 100vh;
  display: flex;
  justify-content: flex-end;
  width: 100vw;
  max-width: 100vw;
}

.dialog-panel {
  width: auto;
  max-width: 100%;
  height: 100vh;
  background: transparent;
  padding: 0;
  display: flex;
}

.dialog-panel > .v-card {
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.12);
}

.detail-panel-wrapper {
  width: 0;
  opacity: 0;
  overflow: hidden;
  transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  margin-right: 0;
}

.detail-panel-wrapper.is-active {
  width: 600px;
  opacity: 1;
  margin-right: 0;
}

.dialog-panel.is-mobile {
  width: 100%;
}

.dialog-panel.is-mobile :deep(.dialog-title) {
  padding: 16px 20px 12px;
}

.dialog-panel.is-mobile :deep(.dialog-toolbar) {
  padding: 8px 12px;
}

.dialog-panel.is-mobile :deep(.dialog-actions) {
  gap: 8px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
}

.dialog-panel.is-mobile :deep(.dialog-actions .v-btn) {
  flex: 1 1 0;
  min-width: 0;
}

.dialog-panel.is-mobile :deep(.v-card-text) {
  padding-bottom: 88px;
}

.detail-panel-wrapper.is-mobile {
  width: 100%;
  opacity: 1;
  overflow: visible;
}

.detail-panel-wrapper.is-mobile.is-active {
  width: 100%;
}

.form-readonly :deep(.v-field) {
  pointer-events: none;
}

@media (max-width: 600px) {
  .dialog-panel {
    width: 100%;
  }

  .dialog-panel > .v-card {
    width: 100%;
    box-shadow: none;
  }
}
</style>
