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

import { listEmployees } from "../api/employees";
import { ApiError } from "../api/http";
import { listSalaryProfiles, saveSalaryProfile } from "../api/salaryProfiles";
import type { EmployeeRecord, SalaryProfileRecord, SalaryProfileRequest } from "../api/types";
import DatePicker from "../components/DatePicker.vue";

const employees = ref<EmployeeRecord[]>([]);
const profiles = ref<SalaryProfileRecord[]>([]);
const loading = ref(false);
const saving = ref(false);
const showEditor = ref(false);
const errorMessage = ref("");
const successMessage = ref("");
const keyword = ref("");

const form = reactive<SalaryProfileRequest>({
  employee_id: 0,
  salary_mode: "monthly",
  base_salary: 0,
  hourly_rate: 0,
  piece_quantity: 0,
  piece_unit_price: 0,
  probation_type: "ratio",
  probation_ratio: 1,
  probation_salary: 0,
  commission_amount: 0,
  overtime_rate: 0,
  weekend_overtime_rate: 0,
  holiday_overtime_rate: 0,
  effective_month: "",
  remark: "",
});

const salaryModeOptions = [
  { value: "monthly", label: "包月" },
  { value: "hourly", label: "计时" },
  { value: "piecework", label: "计件" },
  { value: "probation", label: "试用期" },
];

const totalBaseSalary = computed(() => profiles.value.reduce((total, item) => total + Number(item.base_salary || 0), 0));
const totalCommission = computed(() => profiles.value.reduce((total, item) => total + Number(item.commission_amount || 0), 0));
const avgOvertimeRate = computed(() => {
  if (!profiles.value.length) {
    return 0;
  }
  return profiles.value.reduce((total, item) => total + Number(item.overtime_rate || 0), 0) / profiles.value.length;
});
const editorTitle = computed(() => {
  return profiles.value.some((item) => item.employee_id === form.employee_id) ? "编辑薪资" : "新增薪资";
});

onMounted(loadData);

async function loadData(): Promise<void> {
  loading.value = true;
  errorMessage.value = "";
  try {
    const [employeeRows, profileRows] = await Promise.all([
      listEmployees({ employment_status: "active" }),
      listSalaryProfiles(keyword.value.trim()),
    ]);
    employees.value = employeeRows;
    profiles.value = profileRows;
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "薪资档案加载失败";
  } finally {
    loading.value = false;
  }
}

async function submit(): Promise<void> {
  if (!form.employee_id) {
    errorMessage.value = "请选择关联员工";
    return;
  }

  saving.value = true;
  errorMessage.value = "";
  successMessage.value = "";
  try {
    const profile = await saveSalaryProfile({
      employee_id: Number(form.employee_id),
      salary_mode: form.salary_mode,
      base_salary: Number(form.base_salary || 0),
      hourly_rate: Number(form.hourly_rate || 0),
      piece_quantity: Number(form.piece_quantity || 0),
      piece_unit_price: Number(form.piece_unit_price || 0),
      probation_type: form.probation_type,
      probation_ratio: Number(form.probation_ratio || 1),
      probation_salary: Number(form.probation_salary || 0),
      commission_amount: Number(form.commission_amount || 0),
      overtime_rate: Number(form.overtime_rate || 0),
      weekend_overtime_rate: Number(form.weekend_overtime_rate || 0),
      holiday_overtime_rate: Number(form.holiday_overtime_rate || 0),
      effective_month: form.effective_month || "",
      remark: form.remark.trim(),
    });
    profiles.value = [profile, ...profiles.value.filter((item) => item.employee_id !== profile.employee_id)];
    successMessage.value = "薪资档案已保存";
    showEditor.value = false;
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "薪资档案保存失败";
  } finally {
    saving.value = false;
  }
}

function editProfile(profile: SalaryProfileRecord): void {
  Object.assign(form, {
    employee_id: profile.employee_id,
    salary_mode: profile.salary_mode,
    base_salary: profile.base_salary,
    hourly_rate: profile.hourly_rate,
    piece_quantity: profile.piece_quantity,
    piece_unit_price: profile.piece_unit_price,
    probation_type: profile.probation_type,
    probation_ratio: profile.probation_ratio,
    probation_salary: profile.probation_salary,
    commission_amount: profile.commission_amount,
    overtime_rate: profile.overtime_rate,
    weekend_overtime_rate: profile.weekend_overtime_rate,
    holiday_overtime_rate: profile.holiday_overtime_rate,
    effective_month: profile.effective_month,
    remark: profile.remark,
  });
  successMessage.value = "";
  errorMessage.value = "";
  showEditor.value = true;
}

function openCreateProfile(): void {
  resetForm();
  successMessage.value = "";
  errorMessage.value = "";
  showEditor.value = true;
}

function closeEditor(): void {
  showEditor.value = false;
}

function resetForm(): void {
  Object.assign(form, {
    employee_id: 0,
    salary_mode: "monthly",
    base_salary: 0,
    hourly_rate: 0,
    piece_quantity: 0,
    piece_unit_price: 0,
    probation_type: "ratio",
    probation_ratio: 1,
    probation_salary: 0,
    commission_amount: 0,
    overtime_rate: 0,
    weekend_overtime_rate: 0,
    holiday_overtime_rate: 0,
    effective_month: "",
    remark: "",
  });
}

function salaryModeLabel(value: string): string {
  return salaryModeOptions.find((item) => item.value === value)?.label || value;
}

function profileRuleText(profile: SalaryProfileRecord): string {
  if (profile.salary_mode === "hourly") {
    return `${money(profile.hourly_rate)}/h`;
  }
  if (profile.salary_mode === "piecework") {
    return `${profile.piece_quantity} × ${money(profile.piece_unit_price)}`;
  }
  if (profile.salary_mode === "probation") {
    return profile.probation_type === "fixed"
      ? `固定 ${money(profile.probation_salary)}`
      : `${Math.round(profile.probation_ratio * 100)}%`;
  }
  return money(profile.base_salary);
}

function money(value: number): string {
  return new Intl.NumberFormat("zh-CN", {
    style: "currency",
    currency: "CNY",
    maximumFractionDigits: 2,
  }).format(Number(value || 0));
}
</script>

<template>
  <div class="view-stack salary-profile-page">
    <header class="page-header">
      <div>
        <h1>薪资维护</h1>
        <p>关联员工维护包月、计时、计件、试用期规则和独立加班费单价。</p>
      </div>
    </header>

    <section class="salary-profile-summary-strip" aria-label="薪资档案指标">
      <div class="salary-profile-summary-item">
        <WalletCards :size="18" aria-hidden="true" />
        <span>薪资档案</span>
        <strong>{{ profiles.length }}</strong>
        <small>已维护员工</small>
      </div>
      <div class="salary-profile-summary-item">
        <BadgeDollarSign :size="18" aria-hidden="true" />
        <span>基础工资合计</span>
        <strong>{{ money(totalBaseSalary) }}</strong>
        <small>当前筛选</small>
      </div>
      <div class="salary-profile-summary-item">
        <HandCoins :size="18" aria-hidden="true" />
        <span>提成合计</span>
        <strong>{{ money(totalCommission) }}</strong>
        <small>手工维护</small>
      </div>
      <div class="salary-profile-summary-item">
        <TimerReset :size="18" aria-hidden="true" />
        <span>平均加班单价</span>
        <strong>{{ money(avgOvertimeRate) }}</strong>
        <small>独立维护</small>
      </div>
    </section>

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

    <section class="panel salary-profile-list-panel">
      <div class="panel-header salary-profile-list-header">
        <div>
          <h2>薪资结构一览</h2>
          <p>{{ profiles.length }} 条薪资档案，按员工编号、姓名、部门或岗位查询</p>
        </div>
        <form class="salary-profile-list-tools salary-profile-toolbar" @submit.prevent="loadData">
          <input v-model="keyword" type="search" placeholder="员工姓名、编号、部门..." />
          <button class="secondary-button compact-button" type="submit" :disabled="loading">
            <Loader2 v-if="loading" class="spin" :size="16" aria-hidden="true" />
            <Search v-else :size="16" aria-hidden="true" />
            <span>{{ loading ? "查询中" : "查询" }}</span>
          </button>
          <button class="primary-button compact-button" type="button" @click="openCreateProfile">
            <Plus :size="16" aria-hidden="true" />
            <span>新增档案</span>
          </button>
        </form>
      </div>
      <div v-if="loading" class="empty-state">
        <Loader2 class="spin" :size="18" aria-hidden="true" />
        <p>正在加载薪资档案</p>
      </div>
      <div v-else-if="profiles.length" class="table-wrap">
        <table class="data-table salary-profile-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="profile in profiles" :key="profile.id">
              <td>
                <strong>{{ profile.employee.name }}</strong>
                <span>{{ profile.employee.employee_no }}</span>
              </td>
              <td>
                <strong>{{ profile.employee.department || "-" }}</strong>
                <span>{{ profile.employee.position || "-" }}</span>
              </td>
              <td><span class="status-chip neutral">{{ salaryModeLabel(profile.salary_mode) }}</span></td>
              <td class="mono strong">{{ profileRuleText(profile) }}</td>
              <td class="salary-profile-pay-cell">
                <strong>{{ money(profile.base_salary) }}</strong>
                <span>提成 {{ money(profile.commission_amount) }}</span>
              </td>
              <td>
                <span class="salary-profile-rate-stack">
                  <span>工作日 {{ money(profile.overtime_rate) }}/h</span>
                  <span>周末 {{ money(profile.weekend_overtime_rate) }}/h</span>
                  <span>节假日 {{ money(profile.holiday_overtime_rate) }}/h</span>
                </span>
              </td>
              <td>{{ profile.effective_month || "长期" }}</td>
              <td>
                <button class="link-button" type="button" @click="editProfile(profile)">
                  <Pencil :size="15" aria-hidden="true" />
                  <span>编辑薪资</span>
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-else class="empty-state">
        <p>暂无薪资档案</p>
      </div>
    </section>

    <div v-if="showEditor" class="modal-backdrop salary-profile-edit-modal" @click.self="closeEditor">
      <section class="profile-modal salary-profile-edit-card" aria-label="薪资档案维护">
        <div class="modal-header">
          <div>
            <h2>{{ editorTitle }}</h2>
            <p>在弹出卡片内维护员工当前薪资档案和独立加班单价。</p>
          </div>
          <button class="icon-button" type="button" title="关闭" @click="closeEditor">
            <X :size="18" aria-hidden="true" />
          </button>
        </div>
        <form class="salary-profile-form salary-profile-modal-form" @submit.prevent="submit">
          <section class="salary-profile-modal-section">
            <div class="salary-profile-modal-section-title">
              <strong>基础档案</strong>
              <span>员工、薪资模式和生效月份</span>
            </div>
            <div class="salary-profile-modal-fields">
              <label class="field">
                <span>关联员工</span>
                <select v-model.number="form.employee_id" required>
                  <option :value="0">请选择员工</option>
                  <option v-for="employee in employees" :key="employee.id" :value="employee.id">
                    {{ employee.name }} / {{ employee.employee_no }}
                  </option>
                </select>
              </label>
              <label class="field">
                <span>薪资模式</span>
                <select v-model="form.salary_mode">
                  <option v-for="item in salaryModeOptions" :key="item.value" :value="item.value">
                    {{ item.label }}
                  </option>
                </select>
              </label>
              <label class="field">
                <span>基础工资/底薪</span>
                <input v-model.number="form.base_salary" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>生效月份</span>
                <DatePicker v-model="form.effective_month" mode="month" placeholder="长期" />
              </label>
            </div>
          </section>

          <section class="salary-profile-modal-section">
            <div class="salary-profile-modal-section-title">
              <strong>计时 / 计件 / 试用期</strong>
              <span>按员工类型维护对应口径</span>
            </div>
            <div class="salary-profile-modal-fields">
              <label class="field">
                <span>计时小时单价</span>
                <input v-model.number="form.hourly_rate" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>计件数量</span>
                <input v-model.number="form.piece_quantity" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>计件单价</span>
                <input v-model.number="form.piece_unit_price" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>试用期方式</span>
                <select v-model="form.probation_type">
                  <option value="ratio">固定比例</option>
                  <option value="fixed">固定金额</option>
                </select>
              </label>
              <label class="field">
                <span>试用期比例</span>
                <input v-model.number="form.probation_ratio" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>试用期固定金额</span>
                <input v-model.number="form.probation_salary" min="0" step="0.01" type="number" />
              </label>
            </div>
          </section>

          <section class="salary-profile-modal-section">
            <div class="salary-profile-modal-section-title">
              <strong>提成与加班费</strong>
              <span>提成和不同加班单价单独维护</span>
            </div>
            <div class="salary-profile-modal-fields">
              <label class="field">
                <span>默认提成</span>
                <input v-model.number="form.commission_amount" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>工作日加班单价</span>
                <input v-model.number="form.overtime_rate" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>周末加班单价</span>
                <input v-model.number="form.weekend_overtime_rate" min="0" step="0.01" type="number" />
              </label>
              <label class="field">
                <span>节假日加班单价</span>
                <input v-model.number="form.holiday_overtime_rate" min="0" step="0.01" type="number" />
              </label>
            </div>
          </section>

          <section class="salary-profile-modal-section salary-profile-modal-section-muted">
            <div class="salary-profile-modal-section-title">
              <strong>备注</strong>
              <span>记录特殊薪资说明</span>
            </div>
            <label class="field">
              <span>备注</span>
              <textarea v-model="form.remark" />
            </label>
          </section>

          <p v-if="errorMessage" class="form-error salary-profile-modal-message">{{ errorMessage }}</p>
          <div class="form-actions align-right salary-profile-modal-actions">
            <button class="secondary-button" type="button" @click="resetForm">清空</button>
            <button class="secondary-button" type="button" @click="closeEditor">取消</button>
            <button class="primary-button" type="submit" :disabled="saving">
              <Loader2 v-if="saving" class="spin" :size="18" aria-hidden="true" />
              <Save v-else :size="18" aria-hidden="true" />
              <span>{{ saving ? "保存中" : "保存薪资" }}</span>
            </button>
          </div>
        </form>
      </section>
    </div>
  </div>
</template>
