import { z } from 'zod';
const ratio = z.number().min(0).max(1);
const policyTraceEntrySchema = z.object({
    policyId: z.string().min(1),
    priority: z.number().int(),
    disposition: z.union([z.literal(0), z.literal(1), z.literal(2)]),
    reasonCode: z.string().min(1),
    requestedSellRatioOfLot: ratio,
    appliedSellRatioOfLot: ratio,
    strategicCoreClampApplied: z.boolean()
});
export const researchSellPolicyRequestSchema = z.object({
    positionLotId: z.string().uuid(),
    cycleId: z.string().uuid(),
    evidenceId: z.string().min(1).max(128),
    datasetId: z.string().min(1).max(128),
    modelVersion: z.string().min(1).max(128),
    configVersion: z.string().min(1).max(128),
    codeSha: z.string().min(1).max(128),
    asOf: z.string().datetime({ offset: true }),
    publishedAtCutoff: z.string().datetime({ offset: true }),
    currentSecurityPortfolioWeight: ratio,
    currentLotPortfolioWeight: ratio,
    strategicCoreFloorWeight: ratio,
    hardImpairmentApproved: z.boolean(),
    capitalFloorBreached: z.boolean(),
    survivalSellRatioOfLot: ratio,
    gapBelowFloorAtr: z.number().min(0),
    consecutiveCloseBreaches: z.number().int().min(0),
    cooldownSatisfied: z.boolean(),
    concentrationSellRatioOfLot: ratio,
    opportunityEdgeLowerBound: z.number(),
    opportunitySellRatioOfLot: ratio
}).superRefine((value, ctx) => {
    if (value.currentLotPortfolioWeight > value.currentSecurityPortfolioWeight) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: 'Lot 비중은 종목 전체 비중을 초과할 수 없습니다.',
            path: ['currentLotPortfolioWeight']
        });
    }
    if (new Date(value.publishedAtCutoff) > new Date(value.asOf)) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: '공개 가능 시각은 평가 시각 이후일 수 없습니다.',
            path: ['publishedAtCutoff']
        });
    }
});
export const researchSellPolicyResponseSchema = z.object({
    action: z.enum(['Hold', 'PartialSell', 'FullSell']),
    sellRatioOfLot: ratio,
    targetSecurityPortfolioWeightAfter: ratio,
    policyId: z.string().min(1),
    reasonCode: z.string().min(1),
    decisionContractVersion: z.literal('sell-decision.v2'),
    policyTraceSchemaVersion: z.literal(2),
    reentryEligible: z.boolean(),
    policyTrace: z.array(policyTraceEntrySchema),
    evidenceStatus: z.literal('RESEARCH_CANDIDATE_NOT_PRODUCTION')
});
