<template>
  <section class="system-admin-panel">
    <div class="th-section filter-section">
      <div class="th-section-header">
        <h2 class="th-section-title">{{ t('systemAdmin.users.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.users.keywordPlaceholder')"
            @input="resetToFirstPage"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.users.userStatus') }}</span>
          <select
            v-model="filters.user_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.users.createTitle') }}</h2>
        <p
          v-if="successMessage"
          class="form-message"
        >
          {{ successMessage }}
        </p>
      </div>
      <form
        class="form-grid"
        @submit.prevent="createUser"
      >
        <label>
          <span>{{ t('systemAdmin.users.username') }}</span>
          <input
            v-model="createForm.username"
            type="text"
            autocomplete="off"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.users.initialPassword') }}</span>
          <input
            v-model="createForm.initial_password"
            type="password"
            autocomplete="new-password"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.users.displayName') }}</span>
          <input
            v-model="createForm.display_name"
            type="text"
          >
        </label>
        <label>
          <span>{{ t('systemAdmin.users.userStatus') }}</span>
          <select v-model="createForm.user_status">
            <option value="ACTIVE">{{ t('systemAdmin.status.ACTIVE') }}</option>
            <option value="DISABLED">{{ t('systemAdmin.status.DISABLED') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.users.roles') }}</span>
          <select
            v-model="createForm.role_ids"
            multiple
          >
            <option
              v-for="role in availableRoles"
              :key="role.id"
              :value="role.id"
            >
              {{ role.role_name }}
            </option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.users.hotels') }}</span>
          <select
            v-model="createForm.hotel_ids"
            multiple
          >
            <option
              v-for="hotel in activeHotels"
              :key="hotel.hotel_id"
              :value="hotel.hotel_id"
            >
              {{ hotel.hotel_name }}
            </option>
          </select>
        </label>
        <label>
          <span>{{ t('systemAdmin.users.defaultHotel') }}</span>
          <select v-model="createForm.default_hotel_id">
            <option
              v-for="hotel in activeHotels"
              :key="hotel.hotel_id"
              :value="hotel.hotel_id"
            >
              {{ hotel.hotel_name }}
            </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.users.tableTitle') }}</h2>
            <p class="th-muted">{{ t('workbench.totalPrefix') }} {{ total }} {{ t('systemAdmin.users.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="!users.length"
          class="empty-state"
        >
          {{ t('common.noData') }}
        </div>
        <div
          v-else
          class="table-wrap"
        >
          <table>
            <thead>
              <tr>
                <th>{{ t('systemAdmin.users.columns.user') }}</th>
                <th>{{ t('systemAdmin.users.columns.status') }}</th>
                <th>{{ t('systemAdmin.users.columns.roles') }}</th>
                <th>{{ t('systemAdmin.users.columns.defaultHotel') }}</th>
                <th>{{ t('workbench.columns.updatedAt') }}</th>
                <th>{{ t('workbench.columns.operation') }}</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="user in users"
                :key="user.id"
              >
                <td>
                  <strong>{{ user.display_name || user.username }}</strong>
                  <small class="th-code">{{ user.username }}</small>
                </td>
                <td><span class="status-pill">{{ statusLabel(user.user_status) }}</span></td>
                <td>{{ roleSummary(user.roles) }}</td>
                <td>{{ user.default_hotel_id || '-' }}</td>
                <td>{{ formatReservationDateTime(user.updated_at) }}</td>
                <td>
                  <button
                    type="button"
                    class="row-action"
                    @click="selectUser(user.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.users.detailTitle') }}</h2>
        </div>
        <div
          v-if="detailLoading"
          class="empty-state empty-state--compact"
        >
          {{ t('common.loading') }}
        </div>
        <div
          v-else-if="selectedUser"
          class="detail-list"
        >
          <div>
            <span>{{ t('systemAdmin.users.columns.user') }}</span>
            <strong>{{ selectedUser.display_name || selectedUser.username }}</strong>
            <small class="th-code">{{ selectedUser.id }}</small>
          </div>
          <div>
            <span>{{ t('systemAdmin.users.email') }}</span>
            <strong>{{ selectedUser.email || '-' }}</strong>
          </div>
          <div>
            <span>{{ t('systemAdmin.users.phone') }}</span>
            <strong>{{ selectedUser.phone || '-' }}</strong>
          </div>
          <div>
            <span>{{ t('systemAdmin.users.hotels') }}</span>
            <strong>{{ hotelSummary(selectedUser.hotels) }}</strong>
          </div>
          <form
            class="stacked-form"
            @submit.prevent="updateSelectedUser"
          >
            <label>
              <span>{{ t('systemAdmin.users.displayName') }}</span>
              <input
                v-model="editForm.display_name"
                type="text"
              >
            </label>
            <label>
              <span>{{ t('systemAdmin.users.email') }}</span>
              <input
                v-model="editForm.email"
                type="email"
              >
            </label>
            <label>
              <span>{{ t('systemAdmin.users.phone') }}</span>
              <input
                v-model="editForm.phone"
                type="text"
              >
            </label>
            <label>
              <span>{{ t('systemAdmin.users.userStatus') }}</span>
              <select v-model="editForm.user_status">
                <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"
            >
              {{ t('systemAdmin.common.save') }}
            </button>
          </form>
          <form
            class="stacked-form"
            @submit.prevent="assignSelectedUserRoles"
          >
            <label>
              <span>{{ t('systemAdmin.users.roles') }}</span>
              <select
                v-model="editRoleIds"
                multiple
              >
                <option
                  v-for="role in availableRoles"
                  :key="role.id"
                  :value="role.id"
                >
                  {{ role.role_name }}
                </option>
              </select>
            </label>
            <button
              type="submit"
              class="secondary-button"
              :disabled="saving"
            >
              {{ t('systemAdmin.users.saveRoles') }}
            </button>
          </form>
          <form
            class="stacked-form"
            @submit.prevent="assignSelectedUserHotels"
          >
            <label>
              <span>{{ t('systemAdmin.users.hotels') }}</span>
              <select
                v-model="editHotelIds"
                multiple
              >
                <option
                  v-for="hotel in activeHotels"
                  :key="hotel.hotel_id"
                  :value="hotel.hotel_id"
                >
                  {{ hotel.hotel_name }}
                </option>
              </select>
            </label>
            <label>
              <span>{{ t('systemAdmin.users.defaultHotel') }}</span>
              <select v-model="editDefaultHotelId">
                <option
                  v-for="hotel in activeHotels"
                  :key="hotel.hotel_id"
                  :value="hotel.hotel_id"
                >
                  {{ hotel.hotel_name }}
                </option>
              </select>
            </label>
            <button
              type="submit"
              class="secondary-button"
              :disabled="saving"
            >
              {{ t('systemAdmin.users.saveHotels') }}
            </button>
          </form>
          <button
            type="button"
            class="secondary-button"
            :disabled="saving"
            @click="resetSelectedUserPassword"
          >
            {{ t('systemAdmin.users.resetPassword') }}
          </button>
          <p
            v-if="temporaryPassword"
            class="form-message"
          >
            {{ t('systemAdmin.users.temporaryPassword') }} {{ temporaryPassword }}
          </p>
        </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 {
  assignAdminUserHotels,
  assignAdminUserRoles,
  createAdminUser,
  fetchAdminHotels,
  fetchAdminRoles,
  fetchAdminUserDetail,
  fetchAdminUsers,
  resetAdminUserPassword,
  updateAdminUser,
} from '@/services/systemAdminService'
import type {
  AdminHotelResult,
  AdminRoleListItemResult,
  AdminUserCreateRequest,
  AdminUserDetailResult,
  AdminUserHotelResult,
  AdminUserListFilters,
  AdminUserListItemResult,
  AdminUserRoleResult,
  PlatformPaginationResult,
} from '@/types/systemAdmin'
import { formatReservationDateTime } from '@/utils/reservationFormat'

const { t } = useI18n()
const loading = ref(false)
const detailLoading = ref(false)
const errorMessage = ref('')
const successMessage = ref('')
const saving = ref(false)
const temporaryPassword = ref('')
const users = ref<AdminUserListItemResult[]>([])
const selectedUser = ref<AdminUserDetailResult | null>(null)
const availableRoles = ref<AdminRoleListItemResult[]>([])
const availableHotels = ref<AdminHotelResult[]>([])
const activeHotels = computed(() => availableHotels.value.filter((hotel) => hotel.hotel_status === 'ACTIVE'))
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<AdminUserListFilters>({
  keyword: '',
  user_status: '',
  page_num: 1,
  page_size: 20,
})
const createForm = reactive<AdminUserCreateRequest>({
  username: '',
  initial_password: '',
  display_name: '',
  email: '',
  phone: '',
  user_status: 'ACTIVE',
  role_ids: [],
  hotel_ids: [],
  default_hotel_id: '',
})
const editForm = reactive({
  display_name: '',
  email: '',
  phone: '',
  user_status: 'ACTIVE',
})
const editRoleIds = ref<string[]>([])
const editHotelIds = ref<string[]>([])
const editDefaultHotelId = ref('')
let requestSequence = 0
let detailRequestSequence = 0

onMounted(() => {
  void loadUsers()
  void loadReferenceData()
})

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

async function loadUsers(): Promise<void> {
  const currentRequest = ++requestSequence
  loading.value = true
  errorMessage.value = ''
  try {
    const result = await fetchAdminUsers({ ...filters })
    if (currentRequest !== requestSequence) {
      return
    }
    users.value = result.items
    page.value = result.page
    if (!selectedUser.value && result.items[0]) {
      void selectUser(result.items[0].id)
    }
  } catch (error) {
    if (currentRequest !== requestSequence) {
      return
    }
    users.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 selectUser(userId: string): Promise<void> {
  const currentRequest = ++detailRequestSequence
  detailLoading.value = true
  try {
    const result = await fetchAdminUserDetail(userId)
    if (currentRequest === detailRequestSequence) {
      selectedUser.value = result
      populateEditForms(result)
      temporaryPassword.value = ''
    }
  } finally {
    if (currentRequest === detailRequestSequence) {
      detailLoading.value = false
    }
  }
}

async function loadReferenceData(): Promise<void> {
  const [rolesResult, hotelsResult] = await Promise.all([
    fetchAdminRoles({ page_num: 1, page_size: 100 }),
    fetchAdminHotels({ page_num: 1, page_size: 100 }),
  ])
  availableRoles.value = rolesResult.items
  availableHotels.value = hotelsResult.items
  if (!createForm.default_hotel_id && activeHotels.value[0]) {
    createForm.hotel_ids = [activeHotels.value[0].hotel_id]
    createForm.default_hotel_id = activeHotels.value[0].hotel_id
  }
}

async function createUser(): Promise<void> {
  saving.value = true
  successMessage.value = ''
  errorMessage.value = ''
  try {
    const result = await createAdminUser({ ...createForm })
    successMessage.value = t('systemAdmin.users.created')
    resetCreateForm()
    await loadUsers()
    await selectUser(result.id)
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

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

async function assignSelectedUserRoles(): Promise<void> {
  if (!selectedUser.value) {
    return
  }
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await assignAdminUserRoles(selectedUser.value.id, {
      role_ids: editRoleIds.value,
    })
    selectedUser.value = result
    populateEditForms(result)
    await loadUsers()
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

async function assignSelectedUserHotels(): Promise<void> {
  if (!selectedUser.value) {
    return
  }
  saving.value = true
  errorMessage.value = ''
  try {
    const result = await assignAdminUserHotels(selectedUser.value.id, {
      hotel_ids: editHotelIds.value,
      default_hotel_id: editDefaultHotelId.value,
    })
    selectedUser.value = result
    populateEditForms(result)
    await loadUsers()
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

async function resetSelectedUserPassword(): Promise<void> {
  if (!selectedUser.value) {
    return
  }
  saving.value = true
  temporaryPassword.value = ''
  errorMessage.value = ''
  try {
    const result = await resetAdminUserPassword(selectedUser.value.id)
    temporaryPassword.value = result.temporary_password
  } catch (error) {
    setOperationError(error)
  } finally {
    saving.value = false
  }
}

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

function resetCreateForm(): void {
  createForm.username = ''
  createForm.initial_password = ''
  createForm.display_name = ''
  createForm.email = ''
  createForm.phone = ''
  createForm.user_status = 'ACTIVE'
  createForm.role_ids = []
  createForm.hotel_ids = activeHotels.value[0] ? [activeHotels.value[0].hotel_id] : []
  createForm.default_hotel_id = activeHotels.value[0]?.hotel_id ?? ''
}

function populateEditForms(user: AdminUserDetailResult): void {
  editForm.display_name = user.display_name || ''
  editForm.email = user.email || ''
  editForm.phone = user.phone || ''
  editForm.user_status = user.user_status
  editRoleIds.value = user.roles.map((role) => role.id)
  editHotelIds.value = user.hotels.map((hotel) => hotel.hotel_id)
  editDefaultHotelId.value = user.hotels.find((hotel) => hotel.default_hotel)?.hotel_id ?? editHotelIds.value[0] ?? ''
}

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 roleSummary(roles: AdminUserRoleResult[]): string {
  return roles.map((role) => role.role_name || role.role_code).join(', ') || '-'
}

function hotelSummary(hotels: AdminUserHotelResult[]): string {
  return hotels.map((hotel) => hotel.hotel_name || hotel.hotel_id).join(', ') || '-'
}

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>
