import assert from 'node:assert/strict'
import test from 'node:test'

import { mapExpenseClaimToRequest } from '../src/composables/useRequests.js'

const CREATE_APPLICATION = '\u521b\u5efa\u7533\u8bf7'
const DIRECT_MANAGER_APPROVAL = '\u76f4\u5c5e\u9886\u5bfc\u5ba1\u6279'
const BUDGET_MANAGER_APPROVAL = '\u9884\u7b97\u7ba1\u7406\u8005\u5ba1\u6279'
const APPROVAL_COMPLETED = '\u5ba1\u6279\u5b8c\u6210'
const RETURNED = '\u9000\u56de'
const WAIT_SUBMIT = '\u5f85\u63d0\u4ea4'
const WAIT_LEADER_LI_APPROVAL = '\u7b49\u5f85 Leader Li \u6279\u590d'
const WAIT_BUDGET_ZHAO_APPROVAL = '\u7b49\u5f85 \u8d75\u9884\u7b97 \u6279\u590d'
const LEADER_RETURNED_STATUS = '\u9886\u5bfc\u5df2\u9000\u56de\uff0c\u5f85\u91cd\u65b0\u63d0\u4ea4'

test('application claims are mapped as application documents', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-application-1',
    claim_no: 'AP-20260525103045-ABCDEFGH',
    employee_name: '张三',
    department_name: '交付部',
    manager_name: 'Leader Li',
    expense_type: 'travel_application',
    reason: '支撑国网服务器上线部署',
    location: '上海',
    amount: 12000,
    invoice_count: 0,
    occurred_at: '2026-05-25T00:00:00.000Z',
    submitted_at: '2026-05-25T02:00:00.000Z',
    created_at: '2026-05-25T01:30:00.000Z',
    updated_at: '2026-05-25T02:00:00.000Z',
    status: 'submitted',
    approval_stage: '直属领导审批',
    risk_flags_json: [],
    items: []
  })

  assert.equal(request.documentTypeCode, 'application')
  assert.equal(request.documentTypeLabel, '申请单')
  assert.equal(request.typeLabel, '差旅费用申请')
  assert.equal(request.secondaryStatusLabel, '申请材料')
  assert.equal(request.secondaryStatusValue, '已进入审批流程')
  assert.equal(request.expenseTableSummary, '预计金额已随申请提交')
  assert.deepEqual(
    request.progressSteps.map((step) => step.label),
    [CREATE_APPLICATION, WAIT_LEADER_LI_APPROVAL, BUDGET_MANAGER_APPROVAL, APPROVAL_COMPLETED]
  )
  assert.equal(request.progressSteps.some((step) => step.label === 'AI预审'), false)
  assert.equal(request.progressSteps.some((step) => step.label === '财务审批'), false)
  assert.equal(request.progressSteps.some((step) => step.label === DIRECT_MANAGER_APPROVAL), false)
  assert.equal(request.progressSteps.find((step) => step.label === WAIT_LEADER_LI_APPROVAL)?.rawLabel, DIRECT_MANAGER_APPROVAL)
  assert.equal(request.progressSteps.find((step) => step.label === WAIT_LEADER_LI_APPROVAL)?.current, true)
})

test('application claims wait for department P8 budget monitor after leader approval', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-application-budget',
    claim_no: 'AP-20260525103145-BUDGET',
    employee_name: '张三',
    department_name: '交付部',
    manager_name: 'Leader Li',
    expense_type: 'travel_application',
    reason: '支撑国网服务器上线部署',
    location: '上海',
    amount: 12000,
    invoice_count: 0,
    occurred_at: '2026-05-25T00:00:00.000Z',
    submitted_at: '2026-05-25T02:00:00.000Z',
    created_at: '2026-05-25T01:30:00.000Z',
    updated_at: '2026-05-25T03:00:00.000Z',
    status: 'submitted',
    approval_stage: BUDGET_MANAGER_APPROVAL,
    risk_flags_json: [
      {
        source: 'manual_approval',
        event_type: 'expense_application_approval',
        operator: 'Leader Li',
        previous_approval_stage: DIRECT_MANAGER_APPROVAL,
        next_approval_stage: BUDGET_MANAGER_APPROVAL,
        next_approver_name: '赵预算',
        next_approver_grade: 'P8',
        created_at: '2026-05-25T03:00:00.000Z'
      }
    ],
    items: []
  })

  assert.deepEqual(
    request.progressSteps.map((step) => step.label),
    [CREATE_APPLICATION, DIRECT_MANAGER_APPROVAL, WAIT_BUDGET_ZHAO_APPROVAL, APPROVAL_COMPLETED]
  )
  assert.equal(request.progressSteps.find((step) => step.label === WAIT_BUDGET_ZHAO_APPROVAL)?.current, true)
  assert.equal(request.progressSteps.find((step) => step.label === DIRECT_MANAGER_APPROVAL)?.time, 'Leader Li通过')
})

test('returned application claims include leader return node and supplement status', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-application-returned',
    claim_no: 'APP-20260525-RETURNED',
    employee_name: 'Applicant Zhang',
    department_name: 'Delivery',
    manager_name: 'Leader Li',
    expense_type: 'travel_application',
    reason: 'Project onsite support',
    location: 'Shanghai',
    amount: 12000,
    invoice_count: 0,
    occurred_at: '2026-05-25T00:00:00.000Z',
    submitted_at: null,
    created_at: '2026-05-25T01:30:00.000Z',
    updated_at: '2026-05-25T04:00:00.000Z',
    status: 'returned',
    approval_stage: WAIT_SUBMIT,
    risk_flags_json: [
      {
        source: 'manual_return',
        event_type: 'expense_application_return',
        operator: 'Leader Li',
        opinion: 'Need clearer budget explanation.',
        return_stage_key: 'direct_manager',
        next_status: 'returned',
        next_approval_stage: WAIT_SUBMIT,
        return_count: 2,
        created_at: '2026-05-25T04:00:00.000Z'
      }
    ],
    items: []
  })

  assert.deepEqual(
    request.progressSteps.map((step) => step.label),
    [CREATE_APPLICATION, DIRECT_MANAGER_APPROVAL, RETURNED, WAIT_SUBMIT]
  )
  assert.equal(request.progressSteps.find((step) => step.label === RETURNED)?.time, 'Leader Li\u9000\u56de')
  assert.match(request.progressSteps.find((step) => step.label === RETURNED)?.detail, /2026-05-25/)
  assert.equal(request.progressSteps.find((step) => step.label === WAIT_SUBMIT)?.current, true)
  assert.equal(request.secondaryStatusValue, LEADER_RETURNED_STATUS)
  assert.equal(request.secondaryStatusTone, 'warning')
  assert.equal(request.progressSteps.some((step) => step.label === APPROVAL_COMPLETED), false)
})

test('approved application claims complete after budget approval', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-application-approved',
    claim_no: 'AP-20260525113045-HGFEDCBA',
    employee_name: '张三',
    department_name: '交付部',
    manager_name: '李经理',
    expense_type: 'travel_application',
    reason: '支撑国网服务器上线部署',
    location: '上海',
    amount: 12000,
    invoice_count: 0,
    occurred_at: '2026-05-25T00:00:00.000Z',
    submitted_at: '2026-05-25T02:00:00.000Z',
    created_at: '2026-05-25T01:30:00.000Z',
    updated_at: '2026-05-25T03:00:00.000Z',
    status: 'approved',
    approval_stage: '审批完成',
    risk_flags_json: [
      {
        source: 'manual_approval',
        event_type: 'expense_application_approval',
        operator: '李经理',
        previous_approval_stage: '直属领导审批',
        next_approval_stage: '预算管理者审批',
        next_approver_name: '赵预算',
        next_approver_grade: 'P8',
        created_at: '2026-05-25T03:00:00.000Z'
      },
      {
        source: 'budget_approval',
        event_type: 'expense_application_budget_approval',
        operator: '赵预算',
        previous_approval_stage: '预算管理者审批',
        next_approval_stage: '审批完成',
        created_at: '2026-05-25T03:00:00.000Z'
      }
    ],
    items: []
  })

  assert.equal(request.documentTypeCode, 'application')
  assert.equal(request.workflowNode, '审批完成')
  assert.deepEqual(
    request.progressSteps.map((step) => step.label),
    ['创建申请', '直属领导审批', '预算管理者审批', '审批完成']
  )
  assert.equal(request.progressSteps.every((step) => step.done), true)
  assert.equal(request.progressSteps.find((step) => step.label === '直属领导审批')?.time, '李经理通过')
  assert.equal(request.progressSteps.find((step) => step.label === '预算管理者审批')?.time, '赵预算通过')
})

test('progress steps show approval operator time and current stay duration', () => {
  const originalNow = Date.now
  Date.now = () => new Date('2026-05-20T05:00:00.000Z').getTime()

  try {
    const request = mapExpenseClaimToRequest({
      id: 'claim-1',
      claim_no: 'EXP-202605-001',
      employee_name: '张三',
      department_name: '市场部',
      expense_type: 'transport',
      reason: '交通报销',
      location: '上海',
      amount: 88,
      invoice_count: 1,
      occurred_at: '2026-05-20T01:00:00.000Z',
      submitted_at: '2026-05-20T02:00:00.000Z',
      created_at: '2026-05-20T01:30:00.000Z',
      updated_at: '2026-05-20T03:30:00.000Z',
      status: 'submitted',
      approval_stage: '财务审批',
      risk_flags_json: [
        {
          source: 'manual_approval',
          operator: '李经理',
          previous_approval_stage: '直属领导审批',
          next_approval_stage: '财务审批',
          created_at: '2026-05-20T03:30:00.000Z'
        }
      ],
      items: []
    })

    const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')
    const financeStep = request.progressSteps.find((step) => step.label === '财务审批')
    const aiStep = request.progressSteps.find((step) => step.label === 'AI预审')
    const firstStep = request.progressSteps[0]

    assert.equal(request.riskSummary, '无')
    assert.equal(firstStep.label, '创建单据')
    assert.equal(leaderStep.time, '李经理通过')
    assert.match(leaderStep.detail, /2026-05-20/)
    assert.match(leaderStep.title, /李经理审批通过/)
    assert.equal(aiStep.time, 'AI预审通过')
    assert.match(aiStep.detail, /2026-05-20/)
    assert.equal(financeStep.current, true)
    assert.equal(financeStep.time, '停留 1小时30分钟')
  } finally {
    Date.now = originalNow
  }
})

test('progress steps do not expose approver email when manager name is available', () => {
  const originalNow = Date.now
  Date.now = () => new Date('2026-05-20T05:00:00.000Z').getTime()

  try {
    const request = mapExpenseClaimToRequest({
      id: 'claim-email-operator',
      claim_no: 'EXP-202605-003',
      employee_name: '张三',
      department_name: '市场部',
      manager_name: '李经理',
      expense_type: 'transport',
      reason: '交通报销',
      location: '上海',
      amount: 88,
      invoice_count: 1,
      occurred_at: '2026-05-20T01:00:00.000Z',
      submitted_at: '2026-05-20T02:00:00.000Z',
      created_at: '2026-05-20T01:30:00.000Z',
      updated_at: '2026-05-20T03:30:00.000Z',
      status: 'submitted',
      approval_stage: '财务审批',
      risk_flags_json: [
        {
          source: 'manual_approval',
          operator: 'manager@example.com',
          operator_username: 'manager@example.com',
          previous_approval_stage: '直属领导审批',
          next_approval_stage: '财务审批',
          created_at: '2026-05-20T03:30:00.000Z'
        }
      ],
      items: []
    })

    const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')

    assert.equal(leaderStep.time, '李经理通过')
    assert.ok(!leaderStep.title.includes('manager@example.com'))
  } finally {
    Date.now = originalNow
  }
})

test('travel expense items describe departure return and lodging time below the date', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-travel-time-labels',
    claim_no: 'EXP-202605-TRAVEL',
    employee_name: '张三',
    department_name: '市场部',
    expense_type: 'travel',
    reason: '北京客户现场出差',
    location: '北京',
    amount: 1108,
    invoice_count: 3,
    occurred_at: '2026-05-13T01:00:00.000Z',
    created_at: '2026-05-13T01:30:00.000Z',
    updated_at: '2026-05-13T03:30:00.000Z',
    status: 'draft',
    approval_stage: '待提交',
    risk_flags_json: [],
    items: [
      {
        id: 'outbound-train',
        item_type: 'train_ticket',
        item_reason: '广州南-北京南',
        item_location: '北京',
        item_date: '2026-05-13',
        item_amount: 354,
        invoice_id: 'outbound.png'
      },
      {
        id: 'hotel',
        item_type: 'hotel_ticket',
        item_reason: '北京全季酒店',
        item_location: '北京',
        item_date: '2026-05-14',
        item_amount: 100,
        invoice_id: 'hotel.png'
      },
      {
        id: 'return-train',
        item_type: 'train_ticket',
        item_reason: '北京南-广州南',
        item_location: '广州',
        item_date: '2026-05-15',
        item_amount: 354,
        invoice_id: 'return.png'
      },
      {
        id: 'allowance',
        item_type: 'travel_allowance',
        item_reason: '系统自动计算出差补贴',
        item_location: '北京',
        item_date: '2026-05-15',
        item_amount: 300,
        invoice_id: '',
        is_system_generated: true
      }
    ]
  })

  assert.equal(request.expenseItems.find((item) => item.id === 'outbound-train')?.dayLabel, '出发时间')
  assert.equal(request.expenseItems.find((item) => item.id === 'return-train')?.dayLabel, '返回时间')
  assert.equal(request.expenseItems.find((item) => item.id === 'hotel')?.dayLabel, '住宿时间')
  assert.equal(request.expenseItems.find((item) => item.id === 'outbound-train')?.detail, '起始地-目的地')
  assert.equal(request.expenseItems.find((item) => item.id === 'return-train')?.detail, '起始地-目的地')
  assert.equal(request.expenseItems.find((item) => item.id === 'hotel')?.detail, '目的地酒店')
  assert.equal(request.expenseItems.at(-1)?.id, 'allowance')
  assert.equal(request.expenseItems.at(-1)?.dayLabel, '系统自动计算')
})

test('ticket description helper does not show the destination city as detail text', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-ticket-detail-helper',
    claim_no: 'EXP-202605-ROUTE',
    employee_name: '张三',
    department_name: '市场部',
    expense_type: 'travel',
    reason: '上海项目出差',
    location: '上海',
    amount: 520,
    invoice_count: 2,
    occurred_at: '2026-05-13T01:00:00.000Z',
    created_at: '2026-05-13T01:30:00.000Z',
    updated_at: '2026-05-13T03:30:00.000Z',
    status: 'draft',
    approval_stage: '待提交',
    risk_flags_json: [],
    items: [
      {
        id: 'flight',
        item_type: 'flight_ticket',
        item_reason: '广州白云-上海虹桥',
        item_location: '上海',
        item_date: '2026-05-13',
        item_amount: 320,
        invoice_id: 'flight.png'
      },
      {
        id: 'ship',
        item_type: 'ship_ticket',
        item_reason: '上海港-舟山港',
        item_location: '舟山',
        item_date: '2026-05-14',
        item_amount: 200,
        invoice_id: 'ship.png'
      }
    ]
  })

  assert.equal(request.expenseItems.find((item) => item.id === 'flight')?.detail, '起始地-目的地')
  assert.equal(request.expenseItems.find((item) => item.id === 'ship')?.detail, '起始地-目的地')
  assert.equal(request.expenseItems.find((item) => item.id === 'ship')?.name, '轮船票')
})

test('finance approval moves reimbursement to pending payment step', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-finance-completed',
    claim_no: 'EXP-202605-004',
    employee_name: '张三',
    department_name: '市场部',
    expense_type: 'transport',
    reason: '交通报销',
    location: '上海',
    amount: 88,
    invoice_count: 1,
    occurred_at: '2026-05-20T01:00:00.000Z',
    submitted_at: '2026-05-20T02:00:00.000Z',
    created_at: '2026-05-20T01:30:00.000Z',
    updated_at: '2026-05-20T04:00:00.000Z',
    status: 'pending_payment',
    approval_stage: '待付款',
    risk_flags_json: [
      {
        source: 'manual_approval',
        operator: '李经理',
        previous_approval_stage: '直属领导审批',
        next_approval_stage: '财务审批',
        created_at: '2026-05-20T03:00:00.000Z'
      },
      {
        source: 'finance_approval',
        operator: '财务复核',
        previous_approval_stage: '财务审批',
        next_approval_stage: '待付款',
        created_at: '2026-05-20T04:00:00.000Z'
      }
    ],
    items: []
  })

  const financeStep = request.progressSteps.find((step) => step.label === '财务审批')
  const paymentStep = request.progressSteps.find((step) => step.label === '待付款')

  assert.equal(request.riskSummary, '无')
  assert.equal(request.workflowNode, '待付款')
  assert.equal(request.approvalKey, 'pending_payment')
  assert.equal(financeStep.time, '财务复核通过')
  assert.match(financeStep.detail, /2026-05-20/)
  assert.equal(paymentStep.current, true)
  assert.equal(paymentStep.done, false)
})

test('paid reimbursement marks payment progress step as complete', () => {
  const request = mapExpenseClaimToRequest({
    id: 'claim-finance-paid',
    claim_no: 'EXP-202605-005',
    employee_name: '张三',
    department_name: '市场部',
    expense_type: 'transport',
    reason: '交通报销',
    location: '上海',
    amount: 88,
    invoice_count: 1,
    occurred_at: '2026-05-20T01:00:00.000Z',
    submitted_at: '2026-05-20T02:00:00.000Z',
    created_at: '2026-05-20T01:30:00.000Z',
    updated_at: '2026-05-20T05:00:00.000Z',
    status: 'paid',
    approval_stage: '已付款',
    risk_flags_json: [
      {
        source: 'finance_approval',
        operator: '财务复核',
        previous_approval_stage: '财务审批',
        next_approval_stage: '待付款',
        created_at: '2026-05-20T04:00:00.000Z'
      },
      {
        source: 'payment',
        event_type: 'expense_claim_payment_completed',
        operator: '财务付款',
        previous_approval_stage: '待付款',
        next_approval_stage: '已付款',
        created_at: '2026-05-20T05:00:00.000Z'
      }
    ],
    items: []
  })

  const paymentStep = request.progressSteps.find((step) => step.label === '待付款')
  const paidStep = request.progressSteps.find((step) => step.label === '已付款')

  assert.equal(request.workflowNode, '已付款')
  assert.equal(request.approvalStatus, '已付款')
  assert.equal(paymentStep.time, '待付款')
  assert.equal(paidStep.time, '已付款')
  assert.equal(paidStep.done, true)
})

test('current direct manager step shows how long the claim has stayed there', () => {
  const originalNow = Date.now
  Date.now = () => new Date('2026-05-20T05:15:00.000Z').getTime()

  try {
    const request = mapExpenseClaimToRequest({
      id: 'claim-2',
      claim_no: 'EXP-202605-002',
      employee_name: '王五',
      department_name: '市场部',
      expense_type: 'office',
      reason: '办公用品',
      location: '上海',
      amount: 128,
      invoice_count: 1,
      occurred_at: '2026-05-20T01:00:00.000Z',
      submitted_at: '2026-05-20T02:00:00.000Z',
      created_at: '2026-05-20T01:30:00.000Z',
      updated_at: '2026-05-20T02:00:00.000Z',
      status: 'submitted',
      approval_stage: '直属领导审批',
      risk_flags_json: [],
      items: []
    })

    const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')
    const submitStep = request.progressSteps.find((step) => step.label === '待提交')

    assert.equal(submitStep.time, '王五提交')
    assert.match(submitStep.detail, /2026-05-20/)
    assert.equal(leaderStep.current, true)
    assert.equal(leaderStep.time, '停留 3小时15分钟')
  } finally {
    Date.now = originalNow
  }
})
