import { computed, reactive, ref } from 'vue'
import { useMutation } from '@tanstack/vue-query'
import type { KbxAuditEntry, KbxConflictSnapshot, KbxProblem, KbxValidationError } from '@kbx/contracts'
import { isKbxProblem } from '@kbx/contracts'
import { useKbxDirtyState, useKbxValidation } from '@kbx/ui'
import { orderRegisterSchema } from './order-register.schema'
import { orderRegisterApi, toKbxProblem } from './orderRegisterApi'
import type { OrderLineForm } from './order-register.definition'
import { orderRegisterScreen } from './order-register.definition'
import { kbxTelemetry, startKbxTask } from '../../../telemetry/kbxTelemetryClient'
import type { KbxOrderLifecycleValue } from '../../../../registry/statusCatalog'
interface OrderHeaderForm { orderDate:string;customerId:string|null;warehouseId:string|null;receiverName:string;phone:string;postalCode:string;address1:string;address2:string }
function localDate(){const d=new Date();return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`}
function newLine():OrderLineForm{return{clientId:crypto.randomUUID(),itemId:null,itemCode:'',itemName:'',availableQty:null,orderQty:1,unitPrice:0,amount:0,remark:''}}
export function useOrderRegistration(){
 const orderId=ref<string>();const orderNo=ref<string>();const version=ref<number>();const status=ref<KbxOrderLifecycleValue>('NEW');const auditEntries=ref<KbxAuditEntry[]>([]);const conflict=ref<KbxConflictSnapshot|null>(null);const problem=ref<KbxProblem|null>(null);const failedAction=ref<'save'|'confirm'|null>(null)
 const header=reactive<OrderHeaderForm>({orderDate:localDate(),customerId:null,warehouseId:null,receiverName:'',phone:'',postalCode:'',address1:'',address2:''});const lines=ref<OrderLineForm[]>([newLine()])
 const {dirty,touch,markSaved,reset:resetDirty}=useKbxDirtyState();const validation=useKbxValidation();const mutation=useMutation({mutationFn:orderRegisterApi.save})
 const totalQty=computed(()=>lines.value.reduce((s,l)=>s+Number(l.orderQty||0),0));const totalAmount=computed(()=>lines.value.reduce((s,l)=>s+Number(l.amount||0),0))
 function addLine(){lines.value.push(newLine());touch()}function duplicateLines(source:OrderLineForm[]){if(!source.length)return;lines.value.push(...source.map(l=>({...l,clientId:crypto.randomUUID()})));touch()}function recalc(l:OrderLineForm){l.amount=Number(l.orderQty||0)*Number(l.unitPrice||0)}
 async function onCellChanged(event:{row:OrderLineForm;field:keyof OrderLineForm;newValue:unknown}){if(event.field==='itemCode'){const code=String(event.newValue??'').trim();if(!code)Object.assign(event.row,{itemId:null,itemName:'',availableQty:null});else{const item=await orderRegisterApi.resolveItemByCode(code);if(!item){Object.assign(event.row,{itemId:null,itemName:'',availableQty:null});validation.setRowFieldError(event.row.clientId,'itemCode',{code:'ITEM_NOT_FOUND',message:'존재하지 않는 품목코드입니다. F2로 품목을 조회하세요.'})}else{Object.assign(event.row,{itemId:item.id,itemCode:item.code,itemName:item.displayName});validation.setRowFieldError(event.row.clientId,'itemCode')}}}if(event.field==='orderQty'||event.field==='unitPrice')recalc(event.row);touch()}
 function applyItemLookup(line:OrderLineForm,item:{id:string;code:string;displayName:string}){Object.assign(line,{itemId:item.id,itemCode:item.code,itemName:item.displayName});validation.setRowFieldError(line.clientId,'itemCode');touch()}
 function toValidationErrors():KbxValidationError[]{const parsed=orderRegisterSchema.safeParse({header,lines:lines.value});if(parsed.success)return[];return parsed.error.issues.map(issue=>{const p=issue.path;if(p[0]==='header')return{field:String(p[1]??''),code:'CLIENT_VALIDATION',message:issue.message};if(p[0]==='lines'&&typeof p[1]==='number'){const raw=String(p[2]??'');return{rowKey:lines.value[p[1]]?.clientId,field:raw==='itemId'?'itemCode':raw,code:'CLIENT_VALIDATION',message:issue.message}}return{code:'CLIENT_VALIDATION',message:issue.message}})}
 async function refreshAudit(){auditEntries.value=orderId.value?await orderRegisterApi.audit(orderId.value):[]}
 async function load(id:string){problem.value=null;failedAction.value=null;const r=await orderRegisterApi.get(id);orderId.value=r.orderId;orderNo.value=r.orderNo;version.value=r.version;status.value=r.status;Object.assign(header,{orderDate:r.orderDate,customerId:r.customerId,warehouseId:r.warehouseId,receiverName:r.receiverName,phone:r.phone,postalCode:r.postalCode??'',address1:r.address1,address2:r.address2??''});lines.value=r.lines.map(l=>({...l,availableQty:null}));validation.clear();conflict.value=null;resetDirty();await refreshAudit()}
 async function save(){problem.value=null;failedAction.value=null;const task=startKbxTask(orderRegisterScreen.id,orderRegisterScreen.version,'save-order');validation.clear();const local=toValidationErrors();if(local.length){validation.setErrors(local);task.abandon('client-validation');return false}try{const r=await mutation.mutateAsync({orderId:orderId.value,version:version.value,orderDate:header.orderDate,customerId:header.customerId!,warehouseId:header.warehouseId!,receiverName:header.receiverName,phone:header.phone,postalCode:header.postalCode||undefined,address1:header.address1,address2:header.address2||undefined,lines:lines.value.map(l=>({clientId:l.clientId,itemId:l.itemId!,orderQty:l.orderQty,unitPrice:l.unitPrice,remark:l.remark||undefined}))});orderId.value=r.orderId;orderNo.value=r.orderNo;version.value=r.version;status.value=r.status;markSaved();conflict.value=null;await refreshAudit();task.complete('success');return true}catch(error){const issue=toKbxProblem(error);if(issue?.type==='validation')validation.applyProblem(issue);if(issue?.type==='conflict'&&orderId.value){const latest=await orderRegisterApi.get(orderId.value);conflict.value={code:issue.code,title:issue.title,detail:'입력 중인 주문은 유지됩니다. 최신 값과 비교한 뒤 다시 읽으세요.',entityId:orderId.value,requestedVersion:version.value,currentVersion:issue.currentVersion??latest.version,changes:[['orderDate','주문일'],['customerId','거래처'],['warehouseId','출고창고'],['receiverName','수취인'],['address1','주소']].map(([field,label])=>({field,label,mine:(header as any)[field],latest:(latest as any)[field]}))}}if(issue && !['validation','conflict'].includes(issue.type)){ problem.value=issue; failedAction.value='save' }task.abandon(issue?.type??'system');if(!issue)throw error;return false}}
 async function confirm(){if(!orderId.value||version.value==null||dirty.value)return;problem.value=null;failedAction.value=null;try{const r=await orderRegisterApi.confirm(orderId.value,version.value);version.value=r.version;status.value=r.status;await refreshAudit()}catch(e){if(isKbxProblem(e)&&e.type==='conflict'){const latest=await orderRegisterApi.get(orderId.value);conflict.value={code:e.code,title:e.title,requestedVersion:version.value,currentVersion:e.currentVersion??latest.version,entityId:orderId.value};return}if(isKbxProblem(e)){problem.value=e;failedAction.value='confirm';return}throw e}}
 async function reloadConflict(){if(orderId.value)await load(orderId.value)}
 function dismissConflict(){conflict.value=null}
 async function retryProblem(){const action=failedAction.value;problem.value=null;failedAction.value=null;if(action==='confirm')return confirm();if(action==='save')return save()}
 function dismissProblem(){problem.value=null;failedAction.value=null}
 function createNew(){orderId.value=undefined;orderNo.value=undefined;version.value=undefined;status.value='NEW';Object.assign(header,{orderDate:localDate(),customerId:null,warehouseId:null,receiverName:'',phone:'',postalCode:'',address1:'',address2:''});lines.value=[newLine()];auditEntries.value=[];conflict.value=null;problem.value=null;failedAction.value=null;validation.clear();resetDirty()}
 function copyCurrent(){
  orderId.value=undefined;orderNo.value=undefined;version.value=undefined;status.value='NEW'
  lines.value=lines.value.map(line=>({...line,clientId:crypto.randomUUID()}))
  auditEntries.value=[];conflict.value=null;problem.value=null;failedAction.value=null;validation.clear();resetDirty();touch()
 }
 return{orderId,orderNo,version,status,header,lines,dirty,errors:validation.errors,fieldError:validation.fieldError,totalQty,totalAmount,saving:computed(()=>mutation.isPending.value),auditEntries,conflict,problem,addLine,duplicateLines,onCellChanged,applyItemLookup,save,confirm,load,reloadConflict,dismissConflict,retryProblem,dismissProblem,createNew,copyCurrent,touch}
}
