<script setup lang="ts">
import type { TableColumnsType, TableRowSelection } from 'ant-design-vue';
import dayjs, { type Dayjs } from 'dayjs';
import {
  Button,
  Card,
  Col,
  DatePicker,
  Dropdown,
  Input,
  Menu,
  Modal,
  Row,
  Select,
  Space,
  Statistic,
  Switch,
  Table,
  Tag,
  message,
} from 'ant-design-vue';
import { computed, h, onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';

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

import { STATUS_CONFIG, STATUS_OPTIONS, formatStatus } from './status';

defineOptions({ name: 'FinanceReimbursementList' });

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

const keyword = ref('');
const statusFilter = ref<FinanceApi.TransactionStatus[]>(
  STATUS_OPTIONS.map((item) => item.value),
);
const dateRange = ref<[Dayjs, Dayjs] | null>(null);
const includeDeleted = ref(false);
const selectedRowKeys = ref<number[]>([]);
const batchStatus = ref<FinanceApi.TransactionStatus>('approved');

const RangePicker = DatePicker.RangePicker;

const loading = computed(() => financeStore.loading.reimbursements);

const reimbursements = computed(() =>
  financeStore.reimbursements.slice().sort((a, b) => {
    const statusOrder =
      STATUS_CONFIG[a.status].order - STATUS_CONFIG[b.status].order;
    if (statusOrder !== 0) {
      return statusOrder;
    }
    return dayjs(b.transactionDate).valueOf() -
      dayjs(a.transactionDate).valueOf();
  }),
);

const filteredReimbursements = computed(() => {
  return reimbursements.value.filter((item) => {
    if (!includeDeleted.value && item.isDeleted) {
      return false;
    }
    if (
      statusFilter.value.length > 0 &&
      !statusFilter.value.includes(item.status)
    ) {
      return false;
    }
    if (dateRange.value) {
      const [start, end] = dateRange.value;
      const date = dayjs(item.transactionDate);
      if (
        date.isBefore(start.startOf('day')) ||
        date.isAfter(end.endOf('day'))
      ) {
        return false;
      }
    }
    if (keyword.value.trim().length > 0) {
      const text = keyword.value.trim().toLowerCase();
      const matcher = [
        item.description,
        item.project,
        item.memo,
        item.submittedBy,
        item.reimbursementBatch,
      ]
        .filter(Boolean)
        .join(' ')
        .toLowerCase();
      if (!matcher.includes(text)) {
        return false;
      }
    }
    return true;
  });
});

const statusSummary = computed(() => {
  const summary = new Map<
    FinanceApi.TransactionStatus,
    { count: number; amount: number; baseAmount: number }
  >();
  for (const status of Object.keys(STATUS_CONFIG) as FinanceApi.TransactionStatus[]) {
    summary.set(status, { count: 0, amount: 0, baseAmount: 0 });
  }
  reimbursements.value.forEach((item) => {
    const target = summary.get(item.status);
    if (!target) return;
    target.count += 1;
    target.amount += item.amount;
    target.baseAmount += item.amountInBase ?? 0;
  });
  return Array.from(summary.entries()).sort(
    (a, b) => STATUS_CONFIG[a[0]].order - STATUS_CONFIG[b[0]].order,
  );
});

const columns: TableColumnsType<FinanceApi.Transaction> = [
  {
    title: '报销内容',
    dataIndex: 'description',
    key: 'description',
    ellipsis: true,
  },
  {
    title: '状态',
    key: 'status',
    width: 120,
  },
  {
    title: '日期',
    dataIndex: 'transactionDate',
    key: 'transactionDate',
    width: 140,
  },
  {
    title: '金额',
    key: 'amount',
    width: 160,
  },
  {
    title: '项目/分类',
    key: 'project',
    ellipsis: true,
  },
  {
    title: '提交人',
    dataIndex: 'submittedBy',
    key: 'submittedBy',
    width: 140,
  },
  {
    title: '批次',
    dataIndex: 'reimbursementBatch',
    key: 'reimbursementBatch',
    width: 140,
  },
  {
    title: '操作',
    key: 'actions',
    fixed: 'right',
    width: 220,
  },
];

const rowSelection = computed<TableRowSelection<FinanceApi.Transaction>>(() => ({
  selectedRowKeys: selectedRowKeys.value,
  onChange: (keys) => {
    selectedRowKeys.value = keys as number[];
  },
}));

function resetFilters() {
  keyword.value = '';
  statusFilter.value = STATUS_OPTIONS.map((item) => item.value);
  dateRange.value = null;
  includeDeleted.value = false;
}

async function updateStatus(
  record: FinanceApi.Transaction,
  status: FinanceApi.TransactionStatus,
  extra: Partial<FinanceApi.CreateReimbursementParams> = {},
) {
  await financeStore.updateReimbursement(record.id, {
    status,
    ...extra,
  });
  message.success('状态已更新');
}

function handleApprove(record: FinanceApi.Transaction) {
  updateStatus(record, 'approved');
}

function handleReject(record: FinanceApi.Transaction) {
  let notes = record.reviewNotes ?? '';
  Modal.confirm({
    title: '确认驳回报销申请？',
    content: () =>
      h(Input.TextArea, {
        value: notes,
        placeholder: '请输入驳回原因',
        rows: 3,
        onChange: (event: any) => {
          notes = event.target.value;
        },
      }),
    okText: '驳回',
    cancelText: '取消',
    okButtonProps: { danger: true },
    async onOk() {
      await updateStatus(record, 'rejected', { reviewNotes: notes });
    },
  });
}

function handleMarkPaid(record: FinanceApi.Transaction) {
  updateStatus(record, 'paid', {
    approvedBy: record.approvedBy ?? 'system',
  });
}

function handleMoveToPending(record: FinanceApi.Transaction) {
  updateStatus(record, 'pending');
}

async function handleBulkUpdate(status: FinanceApi.TransactionStatus) {
  if (selectedRowKeys.value.length === 0) return;
  const targets = financeStore.reimbursements.filter((item) =>
    selectedRowKeys.value.includes(item.id),
  );
  await Promise.all(
    targets.map((item) =>
      financeStore.updateReimbursement(item.id, { status }),
    ),
  );
  message.success('批量操作完成');
  selectedRowKeys.value = [];
}

function handleView(record: FinanceApi.Transaction) {
  router.push(`/reimbursement/detail/${record.id}`);
}

function handleCreate() {
  router.push('/reimbursement/create');
}

onMounted(async () => {
  if (financeStore.reimbursements.length === 0) {
    await financeStore.fetchReimbursements();
  }
});
</script>

<template>
  <div class="p-6 space-y-4">
    <Card>
      <template #title>报销概览</template>
      <Row :gutter="16">
        <Col
          v-for="[status, item] in statusSummary"
          :key="status"
          :xs="24"
          :sm="12"
          :md="8"
          :lg="6"
        >
          <Card size="small" :bordered="false">
            <Space direction="vertical" class="w-full">
              <Space align="center">
                <Tag :color="formatStatus(status).color">
                  {{ formatStatus(status).label }}
                </Tag>
                <span class="text-xs text-gray-500">{{
                  formatStatus(status).description
                }}</span>
              </Space>
              <Statistic title="单据数量" :value="item.count" />
              <Statistic
                title="金额（原币）"
                :precision="2"
                :value="item.amount"
              />
              <Statistic
                title="金额（折合CNY）"
                :precision="2"
                :value="item.baseAmount"
              />
            </Space>
          </Card>
        </Col>
      </Row>
    </Card>

    <Card>
      <template #title>筛选条件</template>
      <template #extra>
        <Space>
          <Button type="link" @click="resetFilters">重置</Button>
          <Button type="primary" @click="handleCreate">新增报销</Button>
        </Space>
      </template>
      <Space :size="12" wrap>
        <Input
          v-model:value="keyword"
          allow-clear
          style="width: 240px"
          placeholder="搜索描述 / 项目 / 提交人"
        />
        <Select
          v-model:value="statusFilter"
          :options="STATUS_OPTIONS"
          mode="multiple"
          allow-clear
          placeholder="选择状态"
          style="min-width: 220px"
        />
        <RangePicker
          v-model:value="dateRange"
          allow-clear
          placeholder="请选择日期范围"
        />
        <Space align="center">
          <Switch v-model:checked="includeDeleted" size="small" />
          <span class="text-xs text-gray-500">显示已删除</span>
        </Space>
        <Select
          v-model:value="batchStatus"
          :options="STATUS_OPTIONS"
          style="min-width: 160px"
        />
        <Button
          :disabled="selectedRowKeys.length === 0"
          @click="handleBulkUpdate(batchStatus)"
        >
          批量更新状态
        </Button>
      </Space>
    </Card>

    <Card>
      <template #title>报销列表</template>
      <template #extra>
        <span class="text-sm text-gray-500"
          >共 {{ filteredReimbursements.length }} 条记录</span
        >
      </template>
      <Table
        :columns="columns"
        :data-source="filteredReimbursements"
        :loading="loading"
        :row-key="(record) => record.id"
        :row-selection="rowSelection"
        :scroll="{ x: 960 }"
        bordered
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'status'">
            <Tag :color="formatStatus(record.status).color">
              {{ formatStatus(record.status).label }}
            </Tag>
          </template>

          <template v-else-if="column.key === 'amount'">
            <Space direction="vertical" size="small">
              <span class="font-medium">
                {{ record.amount.toFixed(2) }} {{ record.currency }}
              </span>
              <span class="text-xs text-gray-500">
                折合 {{ record.amountInBase.toFixed(2) }} CNY
              </span>
            </Space>
          </template>

          <template v-else-if="column.key === 'project'">
            <Space direction="vertical" size="small">
              <span class="font-medium">{{ record.project || '未指定' }}</span>
              <span class="text-xs text-gray-500">
                {{ record.memo || '无备注' }}
              </span>
            </Space>
          </template>

          <template v-else-if="column.key === 'actions'">
            <Space>
              <Button size="small" type="link" @click="handleView(record)">
                查看
              </Button>
              <Dropdown>
                <template #overlay>
                  <Menu>
                    <Menu.Item
                      key="approve"
                      @click="handleApprove(record)"
                    >
                      审批通过
                    </Menu.Item>
                    <Menu.Item
                      key="reject"
                      danger
                      @click="handleReject(record)"
                    >
                      驳回
                    </Menu.Item>
                    <Menu.Item key="paid" @click="handleMarkPaid(record)">
                      标记报销
                    </Menu.Item>
                    <Menu.Item
                      key="pending"
                      @click="handleMoveToPending(record)"
                    >
                      重新提交
                    </Menu.Item>
                  </Menu>
                </template>
                <Button size="small">更多</Button>
              </Dropdown>
            </Space>
          </template>
        </template>
      </Table>
    </Card>
  </div>
</template>
