<script setup lang="ts">
import { nextTick, ref } from 'vue'
import { useQuery } from '@tanstack/vue-query'
import { isKbxProblem } from '@kbx/contracts'
import { KbxDataGrid, KbxListPage, KbxSearchPanel, KbxWorkflowBar } from '@kbx/ui'
import { claimColumns, claimScreen, claimSearchFields, claimWorkflow, type ClaimRow } from './claims.definition'
import { claimsApi } from './claimsApi'

type ClaimActionReceipt={actionId:string;requested:number;succeeded:number;failed:number;failures:{claimNo:string;message:string}[]}
const actionLabel:Record<string,string>={approve:'승인',hold:'보류',start:'처리 시작',complete:'처리 완료'}
const allowedTransitions=new Set(Object.keys(actionLabel))
const search=ref<Record<string,unknown>>({status:'REQUESTED'})
const selected=ref<ClaimRow[]>([])
const actionReceipt=ref<ClaimActionReceipt|null>(null)
const receiptEl=ref<HTMLElement|null>(null)
const q=useQuery({queryKey:['oms','claims',search],queryFn:()=>claimsApi.search(search.value),enabled:false})

async function run(){selected.value=[];actionReceipt.value=null;await q.refetch()}
function failureMessage(cause:unknown){return isKbxProblem(cause)?cause.detail||cause.title:cause instanceof Error?cause.message:'업무 전이를 완료하지 못했습니다.'}
async function executeTransition(actionId:string){
  if(!allowedTransitions.has(actionId))return
  const targets=[...selected.value]
  if(!targets.length)return
  if((actionId==='start'||actionId==='complete')&&targets.length!==1)return
  let succeeded=0
  const failures:ClaimActionReceipt['failures']=[]
  for(const row of targets){
    try{await claimsApi.transition(row.id,actionId);succeeded++}
    catch(cause){failures.push({claimNo:row.claimNo,message:failureMessage(cause)})}
  }
  actionReceipt.value={actionId,requested:targets.length,succeeded,failed:failures.length,failures}
  await q.refetch()
  selected.value=[]
  await nextTick();receiptEl.value?.focus()
}
async function command(id:string){if(id==='search')return run();return executeTransition(id)}
</script>

<template>
  <KbxListPage
    :screen="claimScreen"
    :selection-count="selected.length"
    :content-state="q.error.value?'error':q.isFetching.value&&!q.data.value?'loading':!q.data.value?'idle':q.data.value.totalCount===0?'empty':'ready'"
    :refreshing="q.isFetching.value&&Boolean(q.data.value)"
    @command="command"
  >
    <template #search><KbxSearchPanel v-model="search" :fields="claimSearchFields" @search="run" /></template>
    <template #notice>
      <section
        v-if="actionReceipt"
        ref="receiptEl"
        class="claim-action-receipt"
        data-kbx-surface="claim-action-receipt"
        tabindex="-1"
        role="status"
        :data-tone="actionReceipt.failed?'warning':'success'"
      >
        <strong>{{actionLabel[actionReceipt.actionId]}} 결과</strong>
        <span>요청 {{actionReceipt.requested}}건 · 성공 {{actionReceipt.succeeded}}건 · 실패 {{actionReceipt.failed}}건</span>
        <small v-if="actionReceipt.failures.length">{{actionReceipt.failures.map(item=>`${item.claimNo}: ${item.message}`).join(' · ')}}</small>
      </section>
    </template>
    <template #content>
      <KbxWorkflowBar v-if="selected.length===1" :workflow="claimWorkflow" :current="selected[0].status" @transition="command" />
      <KbxDataGrid
        :rows="q.data.value?.items ?? []"
        :columns="claimColumns"
        row-key="id"
        selection="multiple"
        :loading="q.isFetching.value"
        personalization
        exportable
        @selection-changed="selected=$event"
      />
    </template>
    <template #summary>클레임 {{q.data.value?.totalCount ?? 0}}건 · 선택 {{selected.length}}건</template>
  </KbxListPage>
</template>

<style scoped>
.claim-action-receipt{display:grid;grid-template-columns:auto auto minmax(0,1fr);align-items:center;gap:var(--kbx-space-2);min-height:var(--kbx-control-height);padding:var(--kbx-space-2) var(--kbx-space-3);border:var(--kbx-border-width) solid var(--kbx-color-success-border);border-left:var(--kbx-accent-border-width) solid var(--kbx-color-success);background:var(--kbx-color-success-surface);font-size:var(--kbx-font-sm)}
.claim-action-receipt[data-tone="warning"]{border-color:var(--kbx-color-warning-border);border-left-color:var(--kbx-color-warning);background:var(--kbx-color-warning-surface)}
.claim-action-receipt small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--kbx-color-text-muted)}
.claim-action-receipt:focus-visible{outline:calc(var(--kbx-border-width) * 2) solid var(--kbx-color-focus);outline-offset:var(--kbx-space-1)}
</style>
