<script setup lang="ts">
import {
  Loader2,
  Pencil,
  Plus,
  Search,
  UsersRound,
  X,
} from "@lucide/vue";
import { computed, onMounted, reactive, ref } from "vue";

import { ApiError } from "../api/http";
import { createEmployee, getEmployee, listEmployeePage, previewNextEmployeeNo, updateEmployee } from "../api/employees";
import { listDepartments, listPositions } from "../api/organization";
import type { DepartmentRecord, EmployeeRecord, EmployeeRequest, EmploymentStatus, PositionRecord } from "../api/types";

const employees = ref<EmployeeRecord[]>([]);
const departments = ref<DepartmentRecord[]>([]);
const positions = ref<PositionRecord[]>([]);
const loading = ref(false);
const loadingPositions = ref(false);
const loadingEmployeeNo = ref(false);
const saving = ref(false);
const editingId = ref<number | null>(null);
const showEmployeeModal = ref(false);
const errorMessage = ref("");
const successMessage = ref("");
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const activeEmployeeTotal = ref(0);
const filters = reactive({
  employee_info_keyword: "",
  organization_keyword: "",
  employment_status: "",
});

const form = reactive<EmployeeRequest>({
  employee_no: "",
  name: "",
  dingtalk_user_id: "",
  department: "",
  position: "",
  phone: "",
  employment_status: "active",
  remark: "",
});

const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)));
const selectedDepartment = computed(() => departments.value.find((department) => department.name === form.department));
const positionOptions = computed(() => positions.value);
const departmentNames = computed(() => departments.value.map((department) => department.name));
const positionNames = computed(() => positionOptions.value.map((position) => position.name));
let positionRequestVersion = 0;

onMounted(() => {
  refreshEmployees();
  loadOrganization();
});

async function refreshEmployees(): Promise<void> {
  await Promise.all([loadEmployees(), loadActiveEmployeeTotal()]);
}

async function loadNextEmployeeNo(): Promise<void> {
  if (editingId.value) {
    return;
  }
  loadingEmployeeNo.value = true;
  try {
    const response = await previewNextEmployeeNo();
    if (!editingId.value) {
      form.employee_no = response.employee_no;
    }
  } catch (error) {
    form.employee_no = "";
    errorMessage.value = error instanceof ApiError ? error.message : "员工编号生成失败";
  } finally {
    loadingEmployeeNo.value = false;
  }
}

async function loadOrganization(): Promise<void> {
  try {
    const departmentRows = await listDepartments(true);
    departments.value = departmentRows;
    if (form.department) {
      await loadPositionsByDepartment(true);
    }
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "组织架构加载失败";
  }
}

async function loadPositionsByDepartment(keepCurrentPosition = false): Promise<void> {
  const department = selectedDepartment.value;
  positionRequestVersion += 1;
  const currentRequestVersion = positionRequestVersion;
  if (!department) {
    positions.value = [];
    if (!keepCurrentPosition) {
      form.position = "";
    }
    return;
  }
  positions.value = [];
  loadingPositions.value = true;
  try {
    const positionRows = await listPositions(department.id, true);
    if (currentRequestVersion !== positionRequestVersion) {
      return;
    }
    positions.value = positionRows;
    if (!keepCurrentPosition && !positionRows.some((position) => position.name === form.position)) {
      form.position = "";
    }
  } catch (error) {
    if (currentRequestVersion === positionRequestVersion) {
      positions.value = [];
      errorMessage.value = error instanceof ApiError ? error.message : "岗位列表加载失败";
    }
  } finally {
    if (currentRequestVersion === positionRequestVersion) {
      loadingPositions.value = false;
    }
  }
}

async function loadEmployees(): Promise<void> {
  loading.value = true;
  errorMessage.value = "";
  try {
    const response = await listEmployeePage({
      page: page.value,
      page_size: pageSize.value,
      employee_keyword: filters.employee_info_keyword.trim(),
      organization_keyword: filters.organization_keyword.trim(),
      employment_status: filters.employment_status,
    });
    employees.value = response.items;
    total.value = response.total;
    page.value = response.page;
    pageSize.value = response.page_size;
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "员工列表加载失败";
  } finally {
    loading.value = false;
  }
}

async function loadActiveEmployeeTotal(): Promise<void> {
  try {
    const response = await listEmployeePage({
      page: 1,
      page_size: 1,
      employment_status: "active",
    });
    activeEmployeeTotal.value = response.total;
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "在职员工总数加载失败";
  }
}

async function submit(): Promise<void> {
  saving.value = true;
  errorMessage.value = "";
  successMessage.value = "";
  try {
    const payload = normalizedForm();
    const wasEditing = Boolean(editingId.value);
    if (editingId.value) {
      await updateEmployee(editingId.value, payload);
    } else {
      await createEmployee(payload);
    }
    successMessage.value = wasEditing ? "员工档案已更新" : "员工档案已创建";
    resetForm();
    showEmployeeModal.value = false;
    if (!wasEditing) {
      page.value = 1;
    }
    await refreshEmployees();
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "员工档案保存失败";
  } finally {
    saving.value = false;
  }
}

function openCreateModal(): void {
  errorMessage.value = "";
  successMessage.value = "";
  resetForm();
  showEmployeeModal.value = true;
  void loadNextEmployeeNo();
}

async function editEmployee(employee: EmployeeRecord): Promise<void> {
  errorMessage.value = "";
  successMessage.value = "";
  let detail = employee;
  try {
    detail = await getEmployee(employee.id);
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "员工详情加载失败";
    return;
  }
  editingId.value = detail.id;
  Object.assign(form, {
    employee_no: detail.employee_no,
    name: detail.name,
    dingtalk_user_id: detail.dingtalk_user_id,
    department: detail.department,
    position: detail.position,
    phone: detail.phone,
    employment_status: detail.employment_status,
    remark: detail.remark,
  });
  showEmployeeModal.value = true;
  void loadPositionsByDepartment(true);
}

function closeEmployeeModal(): void {
  showEmployeeModal.value = false;
  resetForm();
}

function resetForm(): void {
  editingId.value = null;
  positions.value = [];
  Object.assign(form, {
    employee_no: "",
    name: "",
    dingtalk_user_id: "",
    department: "",
    position: "",
    phone: "",
    employment_status: "active",
    remark: "",
  });
}

function normalizedForm(): EmployeeRequest {
  return {
    employee_no: editingId.value ? form.employee_no.trim() : "",
    name: form.name.trim(),
    dingtalk_user_id: form.dingtalk_user_id.trim(),
    department: form.department.trim(),
    position: form.position.trim(),
    phone: form.phone.trim(),
    employment_status: form.employment_status as EmploymentStatus,
    remark: form.remark.trim(),
  };
}

function handleDepartmentChange(): void {
  form.position = "";
  void loadPositionsByDepartment();
}

function statusLabel(status: string): string {
  return status === "active" ? "在职" : "离职";
}

function searchEmployees(): void {
  page.value = 1;
  loadEmployees();
}

function previousPage(): void {
  if (page.value <= 1) {
    return;
  }
  page.value -= 1;
  loadEmployees();
}

function nextPage(): void {
  if (page.value >= totalPages.value) {
    return;
  }
  page.value += 1;
  loadEmployees();
}
</script>

<template>
  <div class="view-stack employees-page">
    <header class="page-header">
      <div>
        <h1>员工维护</h1>
        <p>管理员工资料，工资核算会优先使用这里的信息。</p>
      </div>
    </header>

    <p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
    <p v-if="successMessage" class="form-success">{{ successMessage }}</p>

    <section class="panel table-panel">
      <div class="panel-header employee-list-header">
        <div class="employee-list-title">
          <h2>员工列表</h2>
          <span class="employee-inline-metric" aria-label="在职员工">
            <UsersRound :size="15" aria-hidden="true" />
            <span>在职员工</span>
            <strong>{{ activeEmployeeTotal }}</strong>
            <em>人</em>
          </span>
        </div>
        <button class="primary-button" type="button" @click="openCreateModal">
          <Plus :size="18" aria-hidden="true" />
          <span>新增员工</span>
        </button>
      </div>
      <form class="table-filter-bar employee-filter-bar" @submit.prevent="searchEmployees">
        <label class="field employee-filter-employee">
          <span>找员工</span>
          <input v-model="filters.employee_info_keyword" type="search" placeholder="输入姓名、编号或手机号" />
        </label>
        <label class="field employee-filter-organization">
          <span>找部门/岗位</span>
          <input v-model="filters.organization_keyword" type="search" placeholder="输入部门或岗位名称" />
        </label>
        <label class="field employee-filter-status">
          <span>状态</span>
          <select v-model="filters.employment_status">
            <option value="">全部状态</option>
            <option value="active">在职</option>
            <option value="inactive">离职</option>
          </select>
        </label>
        <button class="primary-button employee-search-button" type="submit" :disabled="loading">
          <Loader2 v-if="loading" class="spin" :size="18" aria-hidden="true" />
          <Search v-else :size="18" aria-hidden="true" />
          <span>{{ loading ? "查询中" : "查询" }}</span>
        </button>
      </form>
      <div class="table-wrap">
        <table class="data-table">
          <thead>
            <tr>
              <th>员工</th>
              <th>钉钉账号</th>
              <th>部门/岗位</th>
              <th>手机号</th>
              <th>状态</th>
              <th>备注</th>
              <th>更新时间</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="employee in employees" :key="employee.id">
              <td>
                <strong>{{ employee.name }}</strong>
                <span>{{ employee.employee_no }}</span>
              </td>
              <td class="mono">{{ employee.dingtalk_user_id || "未绑定" }}</td>
              <td>
                <strong>{{ employee.department || "-" }}</strong>
                <span>{{ employee.position || "-" }}</span>
              </td>
              <td>{{ employee.phone || "-" }}</td>
              <td>
                <span class="employee-status-pill" :class="employee.employment_status === 'active' ? 'is-active' : 'is-inactive'">
                  <i class="employee-status-dot" aria-hidden="true"></i>
                  {{ statusLabel(employee.employment_status) }}
                </span>
              </td>
              <td class="note-cell">{{ employee.remark || "-" }}</td>
              <td>{{ new Date(employee.updated_at).toLocaleString() }}</td>
              <td>
                <button class="link-button" type="button" @click="editEmployee(employee)">编辑</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-if="!employees.length && !loading" class="empty-state">
        <p>暂无员工档案</p>
      </div>
      <div class="table-pagination">
        <p>第 {{ page }} / {{ totalPages }} 页，共 {{ total }} 条</p>
        <div class="form-actions align-right">
          <button class="secondary-button" type="button" :disabled="loading || page <= 1" @click="previousPage">
            上一页
          </button>
          <button class="secondary-button" type="button" :disabled="loading || page >= totalPages" @click="nextPage">
            下一页
          </button>
        </div>
      </div>
    </section>

    <Teleport to="body">
      <div v-if="showEmployeeModal" class="modal-backdrop" @click.self="closeEmployeeModal">
        <section class="profile-modal employee-modal" aria-label="员工维护">
          <div class="modal-header">
            <div>
              <h2>{{ editingId ? "编辑员工" : "新增员工" }}</h2>
              <p>员工编号由系统生成，部门和岗位按组织架构联动</p>
            </div>
            <button class="icon-button" type="button" title="关闭" @click="closeEmployeeModal">
              <X :size="21" aria-hidden="true" />
            </button>
          </div>

          <form class="form-grid employee-modal-form" @submit.prevent="submit">
            <label class="field">
              <span>员工编号</span>
              <input
                :value="form.employee_no || (loadingEmployeeNo ? '编号生成中' : '保存后自动生成')"
                readonly
                type="text"
              />
            </label>
            <label class="field">
              <span>姓名</span>
              <input v-model="form.name" required maxlength="128" type="text" />
            </label>
            <label class="field">
              <span>钉钉账号</span>
              <input v-model="form.dingtalk_user_id" maxlength="128" placeholder="用于匹配钉钉考勤，可不填" type="text" />
            </label>
            <label class="field">
              <span>状态</span>
              <select v-model="form.employment_status">
                <option value="active">在职</option>
                <option value="inactive">离职</option>
              </select>
            </label>
            <label class="field">
              <span>部门</span>
              <select v-model="form.department" @change="handleDepartmentChange">
                <option value="">请选择部门</option>
                <option v-if="form.department && !departmentNames.includes(form.department)" :value="form.department">
                  {{ form.department }}
                </option>
                <option v-for="department in departments" :key="department.id" :value="department.name">
                  {{ department.name }}
                </option>
              </select>
            </label>
            <label class="field">
              <span>岗位</span>
              <select v-model="form.position" :disabled="!form.department || loadingPositions">
                <option value="">
                  {{ !form.department ? "请先选择部门" : loadingPositions ? "岗位加载中" : "请选择岗位" }}
                </option>
                <option v-if="form.position && !positionNames.includes(form.position)" :value="form.position">
                  {{ form.position }}
                </option>
                <option v-if="form.department && !loadingPositions && !positionOptions.length" disabled value="">
                  该部门暂无岗位
                </option>
                <option v-for="position in positionOptions" :key="position.id" :value="position.name">
                  {{ position.name }}
                </option>
              </select>
            </label>
            <label class="field">
              <span>手机号</span>
              <input v-model="form.phone" maxlength="32" type="tel" />
            </label>
            <label class="field span-row">
              <span>备注</span>
              <textarea v-model="form.remark" />
            </label>
            <p v-if="errorMessage" class="form-error span-row">{{ errorMessage }}</p>
            <p v-if="successMessage" class="form-success span-row">{{ successMessage }}</p>
            <div class="form-actions align-right span-row">
              <button class="secondary-button" type="button" @click="closeEmployeeModal">取消</button>
              <button class="primary-button" type="submit" :disabled="saving">
                <Loader2 v-if="saving" class="spin" :size="18" aria-hidden="true" />
                <Plus v-else-if="!editingId" :size="18" aria-hidden="true" />
                <Pencil v-else :size="18" aria-hidden="true" />
                <span>{{ saving ? "保存中" : editingId ? "保存修改" : "新增员工" }}</span>
              </button>
            </div>
          </form>
        </section>
      </div>
    </Teleport>
  </div>
</template>
