<script setup lang="ts">
import dayjs, { type Dayjs } from 'dayjs';
import type { FormInstance } from 'ant-design-vue';
import {
  Button,
  Card,
  Col,
  DatePicker,
  Form,
  Input,
  InputNumber,
  Row,
  Select,
  Space,
  message,
} from 'ant-design-vue';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';

import type { FinanceApi } from '#/api/core/finance';
import { useFinanceStore } from '#/store/finance';

import { STATUS_OPTIONS } from './status';

defineOptions({ name: 'FinanceReimbursementCreate' });

const financeStore = useFinanceStore();
const router = useRouter();

const formRef = ref<FormInstance>();
const submitting = ref(false);

interface FormState {
  transactionDate: Dayjs | null;
  description: string;
  project?: string;
  categoryId?: number;
  accountId?: number;
  amount: number | null;
  currency: string;
  memo?: string;
  submittedBy?: string;
  reimbursementBatch?: string;
  status: FinanceApi.TransactionStatus;
}

const formState = reactive<FormState>({
  transactionDate: dayjs(),
  description: '',
  project: '',
  categoryId: undefined,
  accountId: undefined,
  amount: null,
  currency: 'CNY',
  memo: '',
  submittedBy: '',
  reimbursementBatch: '',
  status: 'pending',
});

const rules = {
  transactionDate: [{ required: true, message: '请选择报销日期' }],
  description: [{ required: true, message: '请填写报销内容' }],
  amount: [
    { required: true, message: '请输入报销金额' },
    {
      validator(_: unknown, value: number) {
        if (value && value > 0) return Promise.resolve();
        return Promise.reject(new Error('金额必须大于 0'));
      },
    },
  ],
  currency: [{ required: true, message: '请选择币种' }],
};

const currencyOptions = computed(() =>
  financeStore.currencies.map((item) => ({
    label: `${item.name} (${item.code})`,
    value: item.code,
  })),
);

const accountOptions = computed(() =>
  financeStore.accounts.map((item) => ({
    label: `${item.name} · ${item.currency}`,
    value: item.id,
  })),
);

const categoryOptions = computed(() =>
  financeStore.expenseCategories.map((item) => ({
    label: item.name,
    value: item.id,
  })),
);

async function ensureBaseData() {
  await Promise.all([
    financeStore.currencies.length === 0
      ? financeStore.fetchCurrencies()
      : Promise.resolve(),
    financeStore.accounts.length === 0
      ? financeStore.fetchAccounts()
      : Promise.resolve(),
    financeStore.expenseCategories.length === 0
      ? financeStore.fetchCategories()
      : Promise.resolve(),
    financeStore.reimbursements.length === 0
      ? financeStore.fetchReimbursements()
      : Promise.resolve(),
  ]);
}

function buildPayload(): FinanceApi.CreateReimbursementParams {
  return {
    amount: Number(formState.amount),
    transactionDate: formState.transactionDate
      ? formState.transactionDate.format('YYYY-MM-DD')
      : dayjs().format('YYYY-MM-DD'),
    description: formState.description,
    project: formState.project || undefined,
    categoryId: formState.categoryId,
    accountId: formState.accountId,
    currency: formState.currency,
    memo: formState.memo || undefined,
    submittedBy: formState.submittedBy || undefined,
    reimbursementBatch: formState.reimbursementBatch || undefined,
    status: formState.status,
  };
}

async function handleSubmit() {
  if (!formRef.value) return;
  try {
    await formRef.value.validate();
  } catch {
    return;
  }

  submitting.value = true;
  try {
    const payload = buildPayload();
    const reimbursement = await financeStore.createReimbursement(payload);
    message.success('报销申请创建成功');
    router.push(`/reimbursement/detail/${reimbursement.id}`);
  } catch (error) {
    console.error(error);
    message.error('创建报销申请失败，请稍后重试');
  } finally {
    submitting.value = false;
  }
}

function handleCancel() {
  router.back();
}

function resetForm() {
  formRef.value?.resetFields();
  formState.transactionDate = dayjs();
  formState.description = '';
  formState.project = '';
  formState.categoryId = undefined;
  formState.accountId = undefined;
  formState.amount = null;
  formState.currency = 'CNY';
  formState.memo = '';
  formState.submittedBy = '';
  formState.reimbursementBatch = '';
  formState.status = 'pending';
}

onMounted(async () => {
  await ensureBaseData();
});
</script>

<template>
  <div class="p-6">
    <Card class="max-w-4xl mx-auto">
      <template #title>创建报销申请</template>
      <Form
        ref="formRef"
        :model="formState"
        :rules="rules"
        layout="vertical"
        autocomplete="off"
        class="space-y-4"
      >
        <Row :gutter="16">
          <Col :xs="24" :md="12">
            <Form.Item label="报销日期" name="transactionDate">
              <DatePicker
                v-model:value="formState.transactionDate"
                class="w-full"
                format="YYYY-MM-DD"
              />
            </Form.Item>
          </Col>
          <Col :xs="24" :md="12">
            <Form.Item label="报销状态" name="status">
              <Select
                v-model:value="formState.status"
                :options="STATUS_OPTIONS"
                placeholder="选择状态"
              />
            </Form.Item>
          </Col>
        </Row>

        <Form.Item label="报销内容" name="description">
          <Input
            v-model:value="formState.description"
            placeholder="例如：办公设备采购、客户招待等"
          />
        </Form.Item>

        <Row :gutter="16">
          <Col :xs="24" :md="12">
            <Form.Item label="所属项目" name="project">
              <Input
                v-model:value="formState.project"
                placeholder="可填写项目名称或成本中心"
                allow-clear
              />
            </Form.Item>
          </Col>
          <Col :xs="24" :md="12">
            <Form.Item label="费用分类" name="categoryId">
              <Select
                v-model:value="formState.categoryId"
                :options="categoryOptions"
                placeholder="请选择费用分类"
                allow-clear
              />
            </Form.Item>
          </Col>
        </Row>

        <Row :gutter="16">
          <Col :xs="24" :md="12">
            <Form.Item label="支付账号" name="accountId">
              <Select
                v-model:value="formState.accountId"
                :options="accountOptions"
                placeholder="请选择支出账号"
                allow-clear
                show-search
              />
            </Form.Item>
          </Col>
          <Col :xs="24" :md="12">
            <Form.Item label="提交人" name="submittedBy">
              <Input
                v-model:value="formState.submittedBy"
                placeholder="填写报销提交人或责任人"
                allow-clear
              />
            </Form.Item>
          </Col>
        </Row>

        <Row :gutter="16">
          <Col :xs="24" :md="12">
            <Form.Item label="报销金额" name="amount">
              <InputNumber
                v-model:value="formState.amount"
                :precision="2"
                :min="0"
                class="w-full"
                placeholder="请输入金额"
              />
            </Form.Item>
          </Col>
          <Col :xs="24" :md="12">
            <Form.Item label="币种" name="currency">
              <Select
                v-model:value="formState.currency"
                :options="currencyOptions"
                placeholder="请选择币种"
                show-search
              />
            </Form.Item>
          </Col>
        </Row>

        <Form.Item label="报销批次" name="reimbursementBatch">
          <Input
            v-model:value="formState.reimbursementBatch"
            placeholder="可填写批次号或审批编号"
            allow-clear
          />
        </Form.Item>

        <Form.Item label="备注" name="memo">
          <Input.TextArea
            v-model:value="formState.memo"
            :rows="4"
            placeholder="补充说明、附件信息等"
            allow-clear
          />
        </Form.Item>

        <Form.Item>
          <Space>
            <Button type="primary" :loading="submitting" @click="handleSubmit">
              提交
            </Button>
            <Button :disabled="submitting" @click="resetForm">重置</Button>
            <Button :disabled="submitting" @click="handleCancel">取消</Button>
          </Space>
        </Form.Item>
      </Form>
    </Card>
  </div>
</template>
