<script setup lang="ts">
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { fetchGetOvertimeApplicationDetail } from '@/service/api';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import { formatOvertimeDate, formatOvertimeDateTime } from './overtime-application-shared';

defineOptions({ name: 'OvertimeApplicationDetailDialog' });

type ActionType = 'approve' | 'reject';

interface Props {
  rowData?: Api.OvertimeApplication.OvertimeApplication | null;
  showApprovalActions?: boolean;
  actionLoading?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  showApprovalActions: false,
  actionLoading: false
});

const emit = defineEmits<{
  submit: [payload: { actionType: ActionType; reason: string | null }];
}>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const loading = ref(false);
const detailData = ref<Api.OvertimeApplication.OvertimeApplication | null>(null);
const { formRef, validate } = useForm();
const { createRequiredRule } = useFormRules();

const approvalModel = reactive({
  conclusion: 'approve' as ActionType,
  opinion: ''
});

const opinionLabel = computed(() => (approvalModel.conclusion === 'reject' ? '退回原因' : '审批意见'));
const opinionRequired = computed(() => approvalModel.conclusion === 'reject');
const opinionPlaceholder = computed(() => (opinionRequired.value ? `请输入${opinionLabel.value}` : '可填写审批意见'));

const rules = computed(() => ({
  opinion: opinionRequired.value
    ? [
        createRequiredRule(`请输入${opinionLabel.value}`),
        {
          validator: (_rule, value: string, callback) => {
            if (!value?.trim()) {
              callback(new Error(`请输入${opinionLabel.value}`));
              return;
            }

            callback();
          },
          trigger: 'blur'
        }
      ]
    : []
}));

async function loadDetail() {
  if (!props.rowData?.id) {
    detailData.value = null;
    return;
  }

  loading.value = true;
  const { error, data } = await fetchGetOvertimeApplicationDetail(props.rowData.id);
  loading.value = false;

  detailData.value = error || !data ? props.rowData : data;
}

function resetApprovalForm() {
  approvalModel.conclusion = 'approve';
  approvalModel.opinion = '';
  nextTick(() => {
    formRef.value?.clearValidate();
  });
}

watch(opinionRequired, async () => {
  if (!visible.value || !props.showApprovalActions) return;

  await nextTick();
  formRef.value?.clearValidate('opinion');
});

async function handleSubmit() {
  try {
    await validate();
  } catch {
    return;
  }

  emit('submit', {
    actionType: approvalModel.conclusion,
    reason: approvalModel.opinion.trim() || null
  });
}

watch(
  () => visible.value,
  value => {
    if (value) {
      loadDetail();
      resetApprovalForm();
    }
  }
);
</script>

<template>
  <BusinessFormDialog v-model="visible" title="加班申请详情" preset="md" :loading="loading">
    <ElDescriptions v-if="detailData" class="overtime-application-detail-dialog__descriptions" :column="2" border>
      <ElDescriptionsItem label="申请人" label-class-name="overtime-application-detail-dialog__label">
        {{ detailData.applicantName }}
      </ElDescriptionsItem>
      <ElDescriptionsItem label="加班日期" label-class-name="overtime-application-detail-dialog__label--compact">
        {{ formatOvertimeDate(detailData.overtimeDate) }}
      </ElDescriptionsItem>
      <ElDescriptionsItem label="加班时长" label-class-name="overtime-application-detail-dialog__label">
        {{ detailData.overtimeDuration }}
      </ElDescriptionsItem>
      <ElDescriptionsItem label="提交时间" label-class-name="overtime-application-detail-dialog__label--compact">
        {{ formatOvertimeDateTime(detailData.submitTime) }}
      </ElDescriptionsItem>
      <ElDescriptionsItem label="加班原因" :span="2" label-class-name="overtime-application-detail-dialog__label">
        {{ detailData.overtimeReason }}
      </ElDescriptionsItem>
      <ElDescriptionsItem label="加班内容" :span="2" label-class-name="overtime-application-detail-dialog__label">
        {{ detailData.overtimeContent }}
      </ElDescriptionsItem>
    </ElDescriptions>
    <ElEmpty v-else description="未获取到加班申请详情" />

    <div v-if="props.showApprovalActions" class="overtime-application-detail-dialog__approval-form">
      <div class="audit-field">
        <label>审批结论</label>
        <div class="audit-conclusion">
          <button
            type="button"
            class="conclusion-btn"
            :class="{
              active: approvalModel.conclusion === 'approve',
              pass: approvalModel.conclusion === 'approve'
            }"
            @click="approvalModel.conclusion = 'approve'"
          >
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
              <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.5" />
              <path
                d="M5 8.5L7 10.5L11 6"
                stroke="currentColor"
                stroke-width="1.5"
                stroke-linecap="round"
                stroke-linejoin="round"
              />
            </svg>
            通过
          </button>
          <button
            type="button"
            class="conclusion-btn"
            :class="{
              active: approvalModel.conclusion === 'reject',
              reject: approvalModel.conclusion === 'reject'
            }"
            @click="approvalModel.conclusion = 'reject'"
          >
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
              <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.5" />
              <path d="M6 6L10 10M10 6L6 10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
            </svg>
            退回
          </button>
        </div>
      </div>

      <ElForm ref="formRef" :model="approvalModel" :rules="rules" label-position="top" :validate-on-rule-change="false">
        <ElFormItem :label="opinionLabel" prop="opinion">
          <ElInput
            v-model="approvalModel.opinion"
            type="textarea"
            :rows="5"
            maxlength="1000"
            show-word-limit
            :placeholder="opinionPlaceholder"
          />
        </ElFormItem>
      </ElForm>
    </div>

    <template #footer>
      <div class="overtime-application-detail-dialog__footer">
        <ElButton @click="visible = false">取消</ElButton>
        <ElButton
          v-if="props.showApprovalActions"
          type="primary"
          :loading="props.actionLoading"
          :disabled="props.actionLoading || !detailData"
          @click="handleSubmit"
        >
          确认提交
        </ElButton>
      </div>
    </template>
  </BusinessFormDialog>
</template>

<style scoped>
.overtime-application-detail-dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.overtime-application-detail-dialog__approval-form {
  display: grid;
  gap: 18px;
  margin-top: 16px;
}

.audit-field {
  display: grid;
  gap: 8px;
}

.audit-field label {
  color: #475467;
  font-size: 13px;
  font-weight: 800;
}

.audit-conclusion {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.conclusion-btn {
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid #d8e0e8;
  border-radius: 8px;
  background: #fff;
  color: #475467;
  font: inherit;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  transition: all 0.18s ease;
}

.conclusion-btn:hover {
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
}

.conclusion-btn.active.pass {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
}

.conclusion-btn.active.reject {
  border-color: #dc2626;
  background: #fef2f2;
  color: #dc2626;
}

:deep(.overtime-application-detail-dialog__descriptions .el-descriptions__cell) {
  line-height: 1.7;
}

:deep(.overtime-application-detail-dialog__label),
:deep(.overtime-application-detail-dialog__label--compact) {
  white-space: nowrap;
  vertical-align: middle;
}

:deep(.overtime-application-detail-dialog__label) {
  width: 96px;
  min-width: 96px;
}

:deep(.overtime-application-detail-dialog__label--compact) {
  width: 86px;
  min-width: 86px;
}

:deep(.overtime-application-detail-dialog__readonly-input .el-input__wrapper) {
  background: linear-gradient(180deg, rgb(241 245 249 / 98%), rgb(226 232 240 / 94%)), rgb(241 245 249);
  box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
  cursor: default;
}

:deep(.overtime-application-detail-dialog__readonly-input .el-input__wrapper:hover),
:deep(.overtime-application-detail-dialog__readonly-input.is-focus .el-input__wrapper) {
  box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
}

:deep(.overtime-application-detail-dialog__readonly-input .el-input__inner) {
  color: rgb(51 65 85 / 96%);
  cursor: default;
  -webkit-text-fill-color: rgb(51 65 85 / 96%);
}
</style>
