<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { onMounted, reactive, ref } from 'vue'

import {
  fetchFinanceDetails,
  SETTLEMENT_DIFF_THRESHOLD_CENT,
  type FinanceDetail,
} from '@/features/admin/api/adminFinance'
import { adminPath } from '@/shared/utils/adminPath'
import { formatCentWithSymbol } from '@/shared/utils/money'
import { orderStatusLabel } from '@/shared/utils/statusLabels'
import { formatDateTime, formatInputDate } from '@/shared/utils/time'
import AdminTablePagination from '../components/AdminTablePagination.vue'

const loading = ref(false)
const details = ref<FinanceDetail[]>([])
const currentPage = ref(1)
const currentPageSize = ref(20)
const total = ref(0)
const filters = reactive({
  start_date: defaultStartDate(),
  end_date: defaultEndDate(),
  date_type: 'settled',
  order_no: '',
  user_id: '',
  order_status: '',
  settlement_status: '',
})

onMounted(loadDetails)

async function loadDetails() {
  loading.value = true
  try {
    const result = await fetchFinanceDetails({
      ...filters,
      page: currentPage.value,
      page_size: currentPageSize.value,
    })
    details.value = result.items
    total.value = result.total
  } finally {
    loading.value = false
  }
}

function resetFilters() {
  filters.start_date = defaultStartDate()
  filters.end_date = defaultEndDate()
  filters.date_type = 'settled'
  filters.order_no = ''
  filters.user_id = ''
  filters.order_status = ''
  filters.settlement_status = ''
  currentPage.value = 1
  void loadDetails()
}

async function handlePageChange() {
  await loadDetails()
}

function moneyCent(value: number) {
  return formatCentWithSymbol(value)
}

function financeStatusLabel(status: string) {
  const map: Record<string, string> = {
    normal: '正常',
    refund_pending: '退款中',
    refund_failed: '退款失败',
    settlement_diff: '结算差异',
  }
  return map[status] || status
}

function financeStatusType(status: string) {
  if (status === 'normal') return 'success'
  if (status === 'settlement_diff' || status === 'refund_failed') return 'danger'
  if (status === 'refund_pending') return 'warning'
  return 'info'
}

function settlementStatusLabel(status: string) {
  const map: Record<string, string> = {
    unsettled: '未结算',
    settling: '结算中',
    settled: '已结算',
  }
  return map[status] || status || '-'
}

function shortDateTime(value?: string) {
  if (!value) return '-'
  const text = formatDateTime(value)
  return text.replace(/^\d{4}-/, '')
}

function defaultStartDate() {
  const date = new Date()
  date.setDate(date.getDate() - 29)
  return formatInputDate(date)
}

function defaultEndDate() {
  return formatInputDate(new Date())
}
</script>

<template>
  <section class="page finance-details-page">
    <div class="page-header-row">
      <div class="page-header">
        <p class="eyebrow">Finance Details</p>
        <h1>财务明细</h1>
        <p>按订单核对收款、退款、平台收入、号主应得与钱包实际入账。</p>
      </div>
      <div class="toolbar-actions">
        <el-button @click="resetFilters">重置</el-button>
        <el-button type="primary" :icon="Search" :loading="loading" @click="loadDetails">
          查询
        </el-button>
      </div>
    </div>

    <el-form class="filter-panel finance-filter-panel" label-position="top">
      <el-form-item label="日期类型">
        <el-select v-model="filters.date_type" class="full-control">
          <el-option label="结算日期" value="settled" />
          <el-option label="下单日期" value="created" />
        </el-select>
      </el-form-item>
      <el-form-item label="开始日期">
        <el-date-picker
          v-model="filters.start_date"
          class="full-control"
          type="date"
          value-format="YYYY-MM-DD"
        />
      </el-form-item>
      <el-form-item label="结束日期">
        <el-date-picker
          v-model="filters.end_date"
          class="full-control"
          type="date"
          value-format="YYYY-MM-DD"
        />
      </el-form-item>
      <el-form-item label="订单号">
        <el-input v-model="filters.order_no" clearable placeholder="按订单号筛选" />
      </el-form-item>
      <el-form-item label="用户 ID">
        <el-input v-model="filters.user_id" clearable placeholder="租客或号主 ID" />
      </el-form-item>
      <el-form-item label="订单状态">
        <el-select
          v-model="filters.order_status"
          clearable
          placeholder="全部状态"
          class="full-control"
        >
          <el-option label="待支付" value="pending_payment" />
          <el-option label="使用中" value="renting" />
          <el-option label="待结账" value="pending_checkout_confirm" />
          <el-option label="已完成" value="completed" />
          <el-option label="已关闭" value="closed" />
        </el-select>
      </el-form-item>
      <el-form-item label="结算状态">
        <el-select
          v-model="filters.settlement_status"
          clearable
          placeholder="全部结算"
          class="full-control"
        >
          <el-option label="未结算" value="unsettled" />
          <el-option label="已结算" value="settled" />
        </el-select>
      </el-form-item>
    </el-form>

    <div v-loading="loading" class="table-panel finance-details-table">
      <div class="finance-grid-header">
        <div>订单</div>
        <div>状态</div>
        <div>租客/号主</div>
        <div class="amount-cell">收款</div>
        <div class="amount-cell">已退</div>
        <div class="amount-cell">退中</div>
        <div class="amount-cell">净入</div>
        <div class="amount-cell">平台</div>
        <div class="amount-cell">应得</div>
        <div class="amount-cell">入账</div>
        <div class="amount-cell">差异</div>
      </div>

      <div v-if="details.length > 0" class="finance-grid-body">
        <div v-for="row in details" :key="row.order_id" class="finance-grid-row">
          <div class="order-cell">
            <RouterLink class="order-no" :to="adminPath(`orders/${row.order_id}`)">
              {{ row.order_no }}
            </RouterLink>
            <span class="cell-muted">结算 {{ shortDateTime(row.settled_at) }}</span>
          </div>

          <div class="status-stack">
            <span>{{ orderStatusLabel(row.order_status) }}</span>
            <small>{{ settlementStatusLabel(row.settlement_status) }}</small>
            <el-tag size="small" :type="financeStatusType(row.finance_status)">
              {{ financeStatusLabel(row.finance_status) }}
            </el-tag>
          </div>

          <div class="party-cell">
            <span>租 {{ row.renter_phone || row.renter_nickname || row.renter_id }}</span>
            <span>主 {{ row.owner_phone || row.owner_nickname || row.owner_id }}</span>
          </div>

          <span class="amount-text amount-cell">{{ moneyCent(row.paid_amount_cent) }}</span>
          <span class="amount-text amount-cell muted-amount">
            {{ moneyCent(row.refunded_amount_cent) }}
          </span>
          <span class="amount-text amount-cell muted-amount">
            {{ moneyCent(row.refunding_amount_cent) }}
          </span>
          <span class="amount-text amount-cell">{{ moneyCent(row.channel_net_amount_cent) }}</span>
          <span class="amount-text amount-cell">{{
            moneyCent(row.checkout_platform_fee_cent)
          }}</span>
          <span class="amount-text amount-cell">{{
            moneyCent(row.checkout_owner_income_cent)
          }}</span>
          <span class="amount-text amount-cell">{{
            moneyCent(row.owner_wallet_income_amount_cent)
          }}</span>
          <span
            class="amount-text amount-cell"
            :class="{
              'amount-danger':
                Math.abs(row.settlement_diff_amount_cent) >= SETTLEMENT_DIFF_THRESHOLD_CENT,
            }"
          >
            {{ moneyCent(row.settlement_diff_amount_cent) }}
          </span>
        </div>
      </div>

      <el-empty v-else :image-size="80" description="暂无财务明细" />
    </div>

    <AdminTablePagination
      v-if="total > 0"
      v-model:current-page="currentPage"
      v-model:page-size="currentPageSize"
      :total="total"
      :loading="loading"
      @page-change="handlePageChange"
    />
  </section>
</template>

<style scoped>
.finance-details-page {
  --finance-muted: #7f8aa3;
}

.finance-details-page :deep(.page-header-row) {
  margin-bottom: 18px;
}

.finance-details-page :deep(.page-header h1) {
  font-size: 28px;
}

.finance-filter-panel {
  grid-template-columns: 7% 10% 10% 29% 23% 10% 11%;
  gap: 10px;
  margin-bottom: 16px;
  padding: 14px 16px;
}

.finance-filter-panel :deep(.el-form-item__label) {
  margin-bottom: 4px;
  line-height: 18px;
}

.finance-filter-panel :deep(.el-input__wrapper),
.finance-filter-panel :deep(.el-select__wrapper) {
  min-height: 32px;
}

.finance-details-table {
  padding: 0;
}

.finance-grid-header,
.finance-grid-row {
  display: grid;
  grid-template-columns: 15% 9% 16% repeat(8, 7.5%);
  align-items: center;
  width: 100%;
}

.finance-grid-header {
  border-bottom: 1px solid #edf1f7;
  color: #7f8aa3;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0;
  line-height: 1.35;
  text-transform: none;
}

.finance-grid-header > div,
.finance-grid-row > div,
.finance-grid-row > span {
  min-width: 0;
  padding: 8px 7px;
}

.finance-grid-row {
  border-bottom: 1px solid #edf1f7;
}

.finance-grid-row:last-child {
  border-bottom: 0;
}

.order-cell,
.status-stack,
.party-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.order-no {
  display: block;
  max-width: 100%;
  overflow: hidden;
  color: #364152;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell-muted,
.status-stack small,
.party-cell span {
  color: var(--finance-muted);
  font-size: 12px;
}

.status-stack > span {
  color: #364152;
  font-weight: 600;
}

.party-cell span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.amount-text {
  display: block;
  overflow: hidden;
  color: #344054;
  font-size: 12px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.amount-cell {
  text-align: right;
}

.muted-amount {
  color: #667085;
}

.amount-danger {
  color: #dc2626;
  font-weight: 700;
}

@media (max-width: 1440px) {
  .finance-filter-panel {
    grid-template-columns: repeat(4, 1fr);
  }
}
</style>
