<template>
  <section class="system-admin-panel">
    <div class="th-section filter-section">
      <div class="th-section-header">
        <h2 class="th-section-title">{{ t('systemAdmin.menus.title') }}</h2>
        <button
          type="button"
          class="text-button"
          @click="resetFilters"
        >
          {{ t('workbench.reset') }}
        </button>
      </div>
      <div class="filter-grid">
        <label>
          <span>{{ t('systemAdmin.common.keyword') }}</span>
          <input
            v-model="filters.keyword"
            type="search"
            :placeholder="t('systemAdmin.menus.keywordPlaceholder')"
            @input="resetToFirstPage"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.menuStatus') }}</span>
          <select
            v-model="filters.menu_status"
            @change="resetToFirstPage"
          >
            <option value="">{{ t('common.all') }}</option>
            <option value="ACTIVE">{{ t('systemAdmin.status.ACTIVE') }}</option>
            <option value="DISABLED">{{ t('systemAdmin.status.DISABLED') }}</option>
          </select>
        </label>
      </div>
    </div>

    <section class="th-section action-section">
      <div class="th-section-header">
        <h2 class="th-section-title">{{ t('systemAdmin.menus.createTitle') }}</h2>
      </div>
      <form
        class="form-grid"
        @submit.prevent="createMenu"
      >
        <label>
          <span>{{ t('systemAdmin.menus.menuCode') }}</span>
          <input
            v-model="createForm.menu_code"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.menuName') }}</span>
          <input
            v-model="createForm.menu_name"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.route') }}</span>
          <input
            v-model="createForm.route_path"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.permission') }}</span>
          <select v-model="createForm.permission_code">
            <option value="">{{ t('common.all') }}</option>
            <option
              v-for="permission in permissions"
              :key="permission.id"
              :value="permission.permission_code"
            >
              {{ permission.permission_code }}
            </option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.visible') }}</span>
          <select v-model="createForm.visible">
            <option :value="true">{{ t('systemAdmin.common.yes') }}</option>
            <option :value="false">{{ t('systemAdmin.common.no') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.menuStatus') }}</span>
          <select v-model="createForm.menu_status">
            <option value="ACTIVE">{{ t('systemAdmin.status.ACTIVE') }}</option>
            <option value="DISABLED">{{ t('systemAdmin.status.DISABLED') }}</option>
          </select>
        </label>
        <button
          type="submit"
          class="primary-button"
          :disabled="saving"
        >
          {{ t('systemAdmin.common.create') }}
        </button>
      </form>
    </section>

    <section class="th-section table-section">
      <div class="th-section-header">
        <div>
          <h2 class="th-section-title">{{ t('systemAdmin.menus.tableTitle') }}</h2>
          <p class="th-muted">{{ t('workbench.totalPrefix') }} {{ total }} {{ t('systemAdmin.menus.totalSuffix') }}</p>
        </div>
      </div>

      <div
        v-if="loading"
        class="empty-state"
      >
        {{ t('common.loading') }}
      </div>
      <div
        v-else-if="errorMessage"
        class="empty-state empty-state--error"
      >
        {{ errorMessage }}
      </div>
      <div
        v-else-if="!menus.length"
        class="empty-state"
      >
        {{ t('common.noData') }}
      </div>
      <div
        v-else
        class="table-wrap"
      >
        <table>
          <thead>
            <tr>
              <th>{{ t('systemAdmin.menus.columns.menu') }}</th>
              <th>{{ t('systemAdmin.menus.columns.route') }}</th>
              <th>{{ t('systemAdmin.menus.columns.permission') }}</th>
              <th>{{ t('systemAdmin.menus.columns.visible') }}</th>
              <th>{{ t('systemAdmin.menus.columns.status') }}</th>
              <th>{{ t('systemAdmin.menus.columns.sort') }}</th>
              <th>{{ t('systemAdmin.menus.columns.knownRoute') }}</th>
              <th>{{ t('workbench.columns.operation') }}</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="menu in menus"
              :key="menu.id"
            >
              <td>
                <strong>{{ menu.menu_name }}</strong>
                <small class="th-code">{{ menu.menu_code }}</small>
              </td>
              <td>{{ menu.route_path || '-' }}</td>
              <td><span class="code-chip">{{ menu.permission_code || '-' }}</span></td>
              <td>{{ menu.visible ? t('systemAdmin.common.yes') : t('systemAdmin.common.no') }}</td>
              <td><span class="status-pill">{{ statusLabel(menu.menu_status) }}</span></td>
              <td>{{ menu.sort_order ?? '-' }}</td>
              <td>{{ menu.known_route ? t('systemAdmin.common.yes') : t('systemAdmin.common.no') }}</td>
              <td>
                <button
                  type="button"
                  class="row-action"
                  @click="selectMenu(menu)"
                >
                  {{ t('systemAdmin.common.edit') }}
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <footer class="pagination-bar">
        <label class="page-size-control">
          <span>{{ t('common.pageSize') }}</span>
          <select
            v-model.number="filters.page_size"
            @change="resetToFirstPage"
          >
            <option :value="10">10</option>
            <option :value="20">20</option>
            <option :value="50">50</option>
          </select>
        </label>
        <div class="pagination-actions">
          <button
            type="button"
            class="secondary-button"
            :disabled="currentPage <= 1 || loading"
            @click="goToPage(currentPage - 1)"
          >
            {{ t('common.previousPage') }}
          </button>
          <span>{{ t('common.pageStatus', { current: currentPage, total: totalPages }) }}</span>
          <button
            type="button"
            class="secondary-button"
            :disabled="currentPage >= totalPages || loading"
            @click="goToPage(currentPage + 1)"
          >
            {{ t('common.nextPage') }}
          </button>
        </div>
      </footer>
    </section>

    <section
      v-if="selectedMenu"
      class="th-section action-section"
    >
      <div class="th-section-header">
        <h2 class="th-section-title">{{ t('systemAdmin.menus.editTitle') }}</h2>
        <span class="th-code">{{ selectedMenu.menu_code }}</span>
      </div>
      <form
        class="form-grid"
        @submit.prevent="updateSelectedMenu"
      >
        <label>
          <span>{{ t('systemAdmin.menus.menuName') }}</span>
          <input
            v-model="editForm.menu_name"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.route') }}</span>
          <input
            v-model="editForm.route_path"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.componentKey') }}</span>
          <input
            v-model="editForm.component_key"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.iconKey') }}</span>
          <input
            v-model="editForm.icon_key"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.permission') }}</span>
          <select v-model="editForm.permission_code">
            <option value="">{{ t('common.all') }}</option>
            <option
              v-for="permission in permissions"
              :key="permission.id"
              :value="permission.permission_code"
            >
              {{ permission.permission_code }}
            </option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.sort') }}</span>
          <input
            v-model.number="editForm.sort_order"
            type="number"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.columns.visible') }}</span>
          <select v-model="editForm.visible">
            <option :value="true">{{ t('systemAdmin.common.yes') }}</option>
            <option :value="false">{{ t('systemAdmin.common.no') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.menus.menuStatus') }}</span>
          <select v-model="editForm.menu_status">
            <option value="ACTIVE">{{ t('systemAdmin.status.ACTIVE') }}</option>
            <option value="DISABLED">{{ t('systemAdmin.status.DISABLED') }}</option>
          </select>
        </label>
        <button
          type="submit"
          class="primary-button"
          :disabled="saving"
        >
          {{ t('systemAdmin.common.save') }}
        </button>
      </form>
    </section>
  </section>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

import { createAdminMenu, fetchAdminMenus, fetchAdminPermissions, updateAdminMenu } from '@/services/systemAdminService'
import type {
  AdminMenuCreateRequest,
  AdminMenuListFilters,
  AdminMenuResult,
  AdminMenuUpdateRequest,
  AdminPermissionResult,
  PlatformPaginationResult,
} from '@/types/systemAdmin'

const { t } = useI18n()
const loading = ref(false)
const errorMessage = ref('')
const saving = ref(false)
const menus = ref<AdminMenuResult[]>([])
const selectedMenu = ref<AdminMenuResult | null>(null)
const permissions = ref<AdminPermissionResult[]>([])
const page = ref(createPage(1, 20, 0))
const total = computed(() => page.value.total)
const currentPage = computed(() => page.value.page_num)
const totalPages = computed(() => Math.max(1, Math.ceil(page.value.total / Math.max(page.value.page_size, 1))))
const filters = reactive<AdminMenuListFilters>({
  keyword: '',
  menu_status: '',
  page_num: 1,
  page_size: 20,
})
const createForm = reactive<AdminMenuCreateRequest>({
  menu_code: '',
  menu_name: '',
  menu_type: 'PAGE',
  route_path: '',
  component_key: '',
  icon_key: 'pi pi-circle',
  permission_code: '',
  sort_order: 100,
  visible: false,
  menu_status: 'DISABLED',
})
const editForm = reactive<AdminMenuUpdateRequest>({
  menu_name: '',
  menu_type: 'PAGE',
  route_path: '',
  component_key: '',
  icon_key: '',
  permission_code: '',
  sort_order: 0,
  visible: false,
  menu_status: 'DISABLED',
})
let requestSequence = 0

onMounted(() => {
  void loadMenus()
  void loadPermissions()
})

watch(filters, () => {
  void loadMenus()
})

async function loadMenus(): Promise<void> {
  const currentRequest = ++requestSequence
  loading.value = true
  errorMessage.value = ''
  try {
    const result = await fetchAdminMenus({ ...filters })
    if (currentRequest !== requestSequence) {
      return
    }
    menus.value = result.items
    page.value = result.page
  } catch (error) {
    if (currentRequest !== requestSequence) {
      return
    }
    menus.value = []
    page.value = createPage(filters.page_num ?? 1, filters.page_size ?? 20, 0)
    errorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    if (currentRequest === requestSequence) {
      loading.value = false
    }
  }
}

async function loadPermissions(): Promise<void> {
  permissions.value = await fetchAdminPermissions()
}

async function createMenu(): Promise<void> {
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await createAdminMenu({ ...createForm })
    resetCreateForm()
    await loadMenus()
    selectMenu(result)
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

async function updateSelectedMenu(): Promise<void> {
  if (!selectedMenu.value) {
    return
  }
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await updateAdminMenu(selectedMenu.value.id, { ...editForm })
    selectedMenu.value = result
    populateEditForm(result)
    await loadMenus()
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

function resetFilters(): void {
  filters.keyword = ''
  filters.menu_status = ''
  filters.page_num = 1
  filters.page_size = 20
}

function resetCreateForm(): void {
  createForm.menu_code = ''
  createForm.menu_name = ''
  createForm.menu_type = 'PAGE'
  createForm.route_path = ''
  createForm.component_key = ''
  createForm.icon_key = 'pi pi-circle'
  createForm.permission_code = ''
  createForm.sort_order = 100
  createForm.visible = false
  createForm.menu_status = 'DISABLED'
}

function selectMenu(menu: AdminMenuResult): void {
  selectedMenu.value = menu
  populateEditForm(menu)
}

function populateEditForm(menu: AdminMenuResult): void {
  editForm.parent_id = menu.parent_id || ''
  editForm.menu_name = menu.menu_name
  editForm.menu_type = menu.menu_type
  editForm.route_path = menu.route_path || ''
  editForm.component_key = menu.component_key || ''
  editForm.icon_key = menu.icon_key || ''
  editForm.permission_code = menu.permission_code || ''
  editForm.sort_order = menu.sort_order ?? 0
  editForm.visible = menu.visible
  editForm.menu_status = menu.menu_status
}

function resetToFirstPage(): void {
  filters.page_num = 1
}

function goToPage(pageNum: number): void {
  filters.page_num = Math.min(Math.max(pageNum, 1), totalPages.value)
}

function createPage(pageNum: number, pageSize: number, total: number): PlatformPaginationResult {
  return {
    page_num: pageNum,
    page_size: pageSize,
    total,
  }
}

function statusLabel(status: string): string {
  return t(`systemAdmin.status.${status}`)
}

function setOperationError(error: unknown): void {
  errorMessage.value = error instanceof Error ? error.message : String(error)
}
</script>

<style scoped>
@import './system-admin.css';
</style>
