<template>
  <section class="system-admin-panel">
    <div class="th-section filter-section">
      <div class="th-section-header">
        <h2 class="th-section-title">{{ t('systemAdmin.roles.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.roles.keywordPlaceholder')"
            @input="resetToFirstPage"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.roles.roleStatus') }}</span>
          <select
            v-model="filters.role_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.roles.createTitle') }}</h2>
      </div>
      <form
        class="form-grid"
        @submit.prevent="createRole"
      >
        <label>
          <span>{{ t('systemAdmin.roles.roleCode') }}</span>
          <input
            v-model="createForm.role_code"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.roles.roleName') }}</span>
          <input
            v-model="createForm.role_name"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.roles.roleStatus') }}</span>
          <select v-model="createForm.role_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>

    <div class="system-admin-grid">
      <section class="th-section table-section">
        <div class="th-section-header">
          <div>
            <h2 class="th-section-title">{{ t('systemAdmin.roles.tableTitle') }}</h2>
            <p class="th-muted">{{ t('workbench.totalPrefix') }} {{ total }} {{ t('systemAdmin.roles.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="!roles.length"
          class="empty-state"
        >
          {{ t('common.noData') }}
        </div>
        <div
          v-else
          class="table-wrap"
        >
          <table>
            <thead>
              <tr>
                <th>{{ t('systemAdmin.roles.columns.role') }}</th>
                <th>{{ t('systemAdmin.roles.columns.status') }}</th>
                <th>{{ t('systemAdmin.roles.columns.builtin') }}</th>
                <th>{{ t('systemAdmin.roles.columns.permissions') }}</th>
                <th>{{ t('systemAdmin.roles.columns.users') }}</th>
                <th>{{ t('workbench.columns.operation') }}</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="role in roles"
                :key="role.id"
              >
                <td>
                  <strong>{{ role.role_name }}</strong>
                  <small class="th-code">{{ role.role_code }}</small>
                </td>
                <td><span class="status-pill">{{ statusLabel(role.role_status) }}</span></td>
                <td>{{ role.system_builtin ? t('systemAdmin.common.yes') : t('systemAdmin.common.no') }}</td>
                <td>{{ role.permission_count }}</td>
                <td>{{ role.user_count }}</td>
                <td>
                  <button
                    type="button"
                    class="row-action"
                    @click="selectRole(role.id)"
                  >
                    {{ t('systemAdmin.common.viewDetail') }}
                  </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>

      <aside class="th-section detail-panel">
        <div class="th-section-header">
          <h2 class="th-section-title">{{ t('systemAdmin.roles.detailTitle') }}</h2>
        </div>
        <div
          v-if="detailLoading"
          class="empty-state empty-state--compact"
        >
          {{ t('common.loading') }}
        </div>
        <div
          v-else-if="selectedRole"
          class="detail-list"
        >
          <div>
            <span>{{ t('systemAdmin.roles.columns.role') }}</span>
            <strong>{{ selectedRole.role_name }}</strong>
            <small class="th-code">{{ selectedRole.role_code }}</small>
          </div>
          <div>
            <span>{{ t('systemAdmin.roles.columns.permissions') }}</span>
            <strong>{{ selectedRole.permissions.length }}</strong>
          </div>
          <div class="permission-list">
            <span
              v-for="permission in selectedRole.permissions"
              :key="permission.id"
              class="code-chip"
            >
              {{ permission.permission_code }}
            </span>
          </div>
          <p
            v-if="selectedRole.system_builtin"
            class="form-message"
          >
            {{ t('systemAdmin.roles.builtinReadonly') }}
          </p>
          <form
            class="stacked-form"
            @submit.prevent="updateSelectedRole"
          >
            <label>
              <span>{{ t('systemAdmin.roles.roleName') }}</span>
              <input
                v-model="editForm.role_name"
                type="text"
                :disabled="selectedRole.system_builtin"
              >
            </label>
            <label>
              <span>{{ t('systemAdmin.roles.roleStatus') }}</span>
              <select
                v-model="editForm.role_status"
                :disabled="selectedRole.system_builtin"
              >
                <option value="ACTIVE">{{ t('systemAdmin.status.ACTIVE') }}</option>
                <option value="DISABLED">{{ t('systemAdmin.status.DISABLED') }}</option>
              </select>
            </label>
            <button
              type="submit"
              class="secondary-button"
              :disabled="saving || selectedRole.system_builtin"
            >
              {{ t('systemAdmin.common.save') }}
            </button>
          </form>
          <form
            class="stacked-form"
            @submit.prevent="assignSelectedRolePermissions"
          >
            <label>
              <span>{{ t('systemAdmin.roles.columns.permissions') }}</span>
              <select
                v-model="editPermissionIds"
                multiple
                :disabled="selectedRole.system_builtin"
              >
                <option
                  v-for="permission in permissions"
                  :key="permission.id"
                  :value="permission.id"
                >
                  {{ permission.permission_code }}
                </option>
              </select>
            </label>
            <button
              type="submit"
              class="secondary-button"
              :disabled="saving || selectedRole.system_builtin"
            >
              {{ t('systemAdmin.roles.savePermissions') }}
            </button>
          </form>
        </div>
        <div
          v-else
          class="empty-state empty-state--compact"
        >
          {{ t('systemAdmin.common.selectRow') }}
        </div>
      </aside>
    </div>
  </section>
</template>

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

import {
  assignAdminRolePermissions,
  createAdminRole,
  fetchAdminPermissions,
  fetchAdminRoleDetail,
  fetchAdminRoles,
  updateAdminRole,
} from '@/services/systemAdminService'
import type {
  AdminPermissionResult,
  AdminRoleCreateRequest,
  AdminRoleDetailResult,
  AdminRoleListFilters,
  AdminRoleListItemResult,
  PlatformPaginationResult,
} from '@/types/systemAdmin'

const { t } = useI18n()
const loading = ref(false)
const detailLoading = ref(false)
const errorMessage = ref('')
const saving = ref(false)
const roles = ref<AdminRoleListItemResult[]>([])
const permissions = ref<AdminPermissionResult[]>([])
const selectedRole = ref<AdminRoleDetailResult | null>(null)
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<AdminRoleListFilters>({
  keyword: '',
  role_status: '',
  page_num: 1,
  page_size: 20,
})
const createForm = reactive<AdminRoleCreateRequest>({
  role_code: '',
  role_name: '',
  role_status: 'ACTIVE',
})
const editForm = reactive({
  role_name: '',
  role_status: 'ACTIVE',
})
const editPermissionIds = ref<string[]>([])
let requestSequence = 0
let detailRequestSequence = 0

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

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

async function loadRoles(): Promise<void> {
  const currentRequest = ++requestSequence
  loading.value = true
  errorMessage.value = ''
  try {
    const result = await fetchAdminRoles({ ...filters })
    if (currentRequest !== requestSequence) {
      return
    }
    roles.value = result.items
    page.value = result.page
    if (!selectedRole.value && result.items[0]) {
      void selectRole(result.items[0].id)
    }
  } catch (error) {
    if (currentRequest !== requestSequence) {
      return
    }
    roles.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 selectRole(roleId: string): Promise<void> {
  const currentRequest = ++detailRequestSequence
  detailLoading.value = true
  try {
    const result = await fetchAdminRoleDetail(roleId)
    if (currentRequest === detailRequestSequence) {
      selectedRole.value = result
      populateEditForms(result)
    }
  } finally {
    if (currentRequest === detailRequestSequence) {
      detailLoading.value = false
    }
  }
}

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

async function createRole(): Promise<void> {
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await createAdminRole({ ...createForm })
    resetCreateForm()
    await loadRoles()
    await selectRole(result.id)
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

async function updateSelectedRole(): Promise<void> {
  if (!selectedRole.value) {
    return
  }
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await updateAdminRole(selectedRole.value.id, { ...editForm })
    selectedRole.value = result
    populateEditForms(result)
    await loadRoles()
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

async function assignSelectedRolePermissions(): Promise<void> {
  if (!selectedRole.value) {
    return
  }
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await assignAdminRolePermissions(selectedRole.value.id, {
      permission_ids: editPermissionIds.value,
    })
    selectedRole.value = result
    populateEditForms(result)
    await loadRoles()
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

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

function resetCreateForm(): void {
  createForm.role_code = ''
  createForm.role_name = ''
  createForm.role_status = 'ACTIVE'
}

function populateEditForms(role: AdminRoleDetailResult): void {
  editForm.role_name = role.role_name
  editForm.role_status = role.role_status
  editPermissionIds.value = role.permissions.map((permission) => permission.id)
}

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>
