<script setup lang="ts">
import { computed, ref, reactive } from 'vue'
import StepWizardPage from '../../../shared/ui/screen-types/v2/StepWizardPage.vue'
import DataGridShell from '../../../shared/ui/DataGridShell.vue'
import { KsButton, KsCheckbox, KsFormGrid, KsFormSection, KsNumberField, KsStatusTag, KsTextField } from '../../../shared/ui/components'
import type { UiGridColumn } from '../../../shared/ui/adapter/contracts'
import { formatCurrency, formatPercent, formatQuantity } from '../../../shared/formatters/financial'
import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract'

// KBX T06 Governance Audit & Screen State
const screenState = ref<StandardScreenState>('READY')
const currentStep = ref(1)

const evidence = reactive({
  asOf: new Date().toISOString(),
  version: 'v60-T06-Contract',
})

interface Position {
  symbol: string
  name: string
  quantity: number
  marketPrice: number
  marketValue: number
  weightPercent: number
}

interface TargetWeight {
  symbol: string
  targetPercent: number
}

interface SimulationItem {
  symbol: string
  currentQuantity: number
  marketPrice: number
  currentValue: number
  currentWeight: number
  targetWeight: number
  targetValue: number
  deltaValue: number
  tradeAction: 'BUY' | 'SELL' | 'HOLD'
  estimatedShares: number
}

interface JobResult {
  jobId: string
  status: string
  submittedAt: string
  estimatedTradeCount: number
  estimatedCost: number
  totalRebalanceValue: number
}

const currentPositions = ref<Position[]>([
  { symbol: 'AAPL', name: '애플', quantity: 100, marketPrice: 185.20, marketValue: 18520, weightPercent: 35.3 },
  { symbol: 'NVDA', name: '엔비디아', quantity: 30, marketPrice: 875.50, marketValue: 26265, weightPercent: 50.1 },
  { symbol: 'MSFT', name: '마이크로소프트', quantity: 18, marketPrice: 415.00, marketValue: 7470, weightPercent: 14.6 },
])

const driftThreshold = ref(3)
const targetWeights = ref<TargetWeight[]>([
  { symbol: 'AAPL', targetPercent: 30 },
  { symbol: 'NVDA', targetPercent: 40 },
  { symbol: 'MSFT', targetPercent: 30 },
])

const jobResult = ref<JobResult | null>(null)

const positionColumns: UiGridColumn[] = [
  { field: 'symbol', header: '종목코드', width: 90 },
  { field: 'quantity', header: '현재수량', formatter: value => formatQuantity(value as number, 0) },
  { field: 'marketPrice', header: '현재가', formatter: value => formatCurrency(value as number, 'USD') },
  { field: 'marketValue', header: '평가금액', formatter: value => formatCurrency(value as number, 'USD') },
  { field: 'weightPercent', header: '현재비중', formatter: value => formatPercent((value as number) / 100, 1) }
]

const simulationColumns: UiGridColumn[] = [
  { field: 'symbol', header: '종목코드', width: 90 },
  { field: 'currentWeight', header: '현재비중', formatter: value => formatPercent((value as number) / 100, 1) },
  { field: 'targetWeight', header: '목표비중', formatter: value => formatPercent((value as number) / 100, 1) },
  { field: 'tradeAction', header: '매매구분', width: 90 },
  { field: 'estimatedShares', header: '예상주문주수', formatter: value => formatQuantity(value as number, 0) },
  { field: 'deltaValue', header: '예상조정금액', formatter: value => formatCurrency(value as number, 'USD') }
]

const totalValue = computed(() => {
  return currentPositions.value.reduce((sum, p) => sum + p.marketValue, 0)
})

const totalTargetWeight = computed(() => {
  return targetWeights.value.reduce((sum, t) => sum + (t.targetPercent || 0), 0)
})

const isWeightValid = computed(() => {
  return Math.abs(totalTargetWeight.value - 100) < 0.01
})

const weightStatusSeverity = computed(() => {
  if (isWeightValid.value) return 'success'
  if (totalTargetWeight.value > 100) return 'danger'
  return 'warning'
})

const weightStatusText = computed(() => {
  if (isWeightValid.value) return '✅ 100.0% 정상'
  if (totalTargetWeight.value > 100) return `⚠️ ${totalTargetWeight.value.toFixed(1)}% (100% 초과)`
  return `⚠️ ${totalTargetWeight.value.toFixed(1)}% (100% 미달)`
})

const simulationItems = computed<SimulationItem[]>(() => {
  const total = totalValue.value
  return targetWeights.value.map(target => {
    const pos = currentPositions.value.find(p => p.symbol === target.symbol)
    const currentVal = pos ? pos.marketValue : 0
    const currentQty = pos ? pos.quantity : 0
    const price = pos ? pos.marketPrice : 150
    const currentW = total > 0 ? (currentVal / total) * 100 : 0
    const targetW = target.targetPercent || 0
    const targetVal = total * (targetW / 100)
    const deltaV = targetVal - currentVal

    let tradeAction: 'BUY' | 'SELL' | 'HOLD' = 'HOLD'
    if (deltaV > 50) tradeAction = 'BUY'
    else if (deltaV < -50) tradeAction = 'SELL'

    const estimatedShares = price > 0 ? Math.round(Math.abs(deltaV) / price) : 0

    return {
      symbol: target.symbol,
      currentQuantity: currentQty,
      marketPrice: price,
      currentValue: currentVal,
      currentWeight: currentW,
      targetWeight: targetW,
      targetValue: targetVal,
      deltaValue: deltaV,
      tradeAction,
      estimatedShares
    }
  })
})

const totalEstimatedTrades = computed(() => {
  return simulationItems.value.filter(item => item.tradeAction !== 'HOLD').length
})

const totalRebalanceValue = computed(() => {
  return simulationItems.value.reduce((sum, item) => sum + Math.abs(item.deltaValue), 0)
})

const addTarget = () => {
  targetWeights.value.push({ symbol: '', targetPercent: 0 })
}

const removeTarget = (idx: number) => {
  targetWeights.value.splice(idx, 1)
}

const nextStep = () => {
  if (currentStep.value === 1 && !isWeightValid.value) return
  if (currentStep.value < 3) currentStep.value++
}

const prevStep = () => {
  if (currentStep.value > 1) currentStep.value--
}

const triggerRebalance = () => {
  jobResult.value = {
    jobId: `REBAL-${Date.now()}`,
    status: 'Queued',
    submittedAt: new Date().toLocaleTimeString('ko-KR'),
    estimatedTradeCount: totalEstimatedTrades.value,
    estimatedCost: totalRebalanceValue.value * 0.0015,
    totalRebalanceValue: totalRebalanceValue.value
  }
  currentStep.value = 3
}

const resetWizard = () => {
  jobResult.value = null
  currentStep.value = 1
}

const handleRetry = () => {
  screenState.value = 'READY'
}
</script>

<template>
  <StepWizardPage
    title="포트폴리오 리밸런싱 위저드"
    subtitle="목표 비중 및 허용 이탈 임계값을 설정하여 리밸런싱 시뮬레이션 및 주문 제출을 안전하게 수행합니다."
    :state="screenState"
    :evidence="evidence"
    :current-step="currentStep"
    :total-steps="3"
    @retry="handleRetry"
  >
    <!-- Wizard Actions Header Slot -->
    <template #actions>
      <KsButton v-if="currentStep > 1 && currentStep < 3" variant="secondary" label="◀ 이전 단계" @click="prevStep" />
      <KsButton v-if="currentStep === 1" variant="primary" label="다음 단계: 시뮬레이션 ➔" :disabled="!isWeightValid" @click="nextStep" />
      <KsButton v-if="currentStep === 2" variant="primary" label="⚡ 리밸런싱 주문 제출" @click="triggerRebalance" />
      <KsButton v-if="currentStep === 3" variant="secondary" label="🔄 신규 리밸런싱 작성" @click="resetWizard" />
    </template>

    <div class="ks-wizard-content">
      <!-- Step 1: Target Weight Definition -->
      <div v-if="currentStep === 1" class="wizard-step-pane step1-grid">
        <KsFormSection title="1-1. 현재 포트폴리오 보유 현황">
          <DataGridShell :rows="currentPositions" :columns="positionColumns" empty-message="보유 종목이 없습니다." height="220px" />
          <div class="summary-bar">
            <span><strong>총 평가액:</strong> <span class="ks-financial-number">{{ formatCurrency(totalValue, 'USD') }}</span></span>
            <span><strong>보유 종목 수:</strong> {{ currentPositions.length }}개</span>
          </div>
        </KsFormSection>

        <KsFormSection title="1-2. 목표 비중 및 이탈 임계값 설정">
          <div class="threshold-row">
            <KsNumberField v-model="driftThreshold" label="허용 이탈 임계값 %" :min="0" :max="50" :max-fraction-digits="1" />
            <div class="weight-total-badge">
              <span class="label">목표 비중 합계:</span>
              <KsStatusTag :value="weightStatusText" :severity="weightStatusSeverity" />
            </div>
          </div>

          <div class="targets-container">
            <div v-for="(target, idx) in targetWeights" :key="idx" class="target-card-row">
              <KsTextField v-model="target.symbol" label="종목코드" :input-id="`target-symbol-${idx}`" style="width: 130px;" />
              <KsNumberField v-model="target.targetPercent" label="목표 비중 %" :min="0" :max="100" :max-fraction-digits="1" :input-id="`target-percent-${idx}`" style="width: 140px;" />
              <KsButton variant="danger" label="삭제" :disabled="targetWeights.length <= 1" @click="removeTarget(idx)" />
            </div>
            <div class="target-actions">
              <KsButton variant="secondary" label="➕ 종목 추가" @click="addTarget" />
            </div>
          </div>
        </KsFormSection>
      </div>

      <!-- Step 2: Trade Simulation Preview -->
      <div v-if="currentStep === 2" class="wizard-step-pane">
        <KsFormSection title="2-1. 리밸런싱 매매 시뮬레이션 결과">
          <DataGridShell :rows="simulationItems" :columns="simulationColumns" empty-message="시뮬레이션 항목이 없습니다." height="220px" />

          <div class="summary-bar">
            <span><strong>예상 주문 건수:</strong> <span class="ks-financial-number">{{ totalEstimatedTrades }}건</span></span>
            <span><strong>예상 리밸런싱 거래 규모:</strong> <span class="ks-financial-number">{{ formatCurrency(totalRebalanceValue, 'USD') }}</span></span>
            <span><strong>예상 수수료:</strong> <span class="ks-financial-number">{{ formatCurrency(totalRebalanceValue * 0.0015, 'USD') }}</span></span>
          </div>
        </KsFormSection>

        <KsFormSection title="2-2. 상세 조정 내역 확인">
          <div class="simulation-detail-grid">
            <div v-for="item in simulationItems" :key="item.symbol" class="sim-item-card">
              <div class="sim-item-header">
                <span class="symbol">{{ item.symbol }}</span>
                <KsStatusTag :value="item.tradeAction === 'BUY' ? '매수 BUY' : item.tradeAction === 'SELL' ? '매도 SELL' : '유지 HOLD'" :severity="item.tradeAction === 'BUY' ? 'success' : item.tradeAction === 'SELL' ? 'danger' : 'info'" />
              </div>
              <div class="sim-item-body">
                <div><span>현재 비중:</span> <strong>{{ formatPercent(item.currentWeight / 100, 1) }}</strong></div>
                <div><span>목표 비중:</span> <strong>{{ formatPercent(item.targetWeight / 100, 1) }}</strong></div>
                <div><span>예상 수량:</span> <strong>{{ formatQuantity(item.estimatedShares, 0) }} 주</strong></div>
                <div><span>예상 금액:</span> <strong>{{ formatCurrency(Math.abs(item.deltaValue), 'USD') }}</strong></div>
              </div>
            </div>
          </div>
        </KsFormSection>
      </div>

      <!-- Step 3: Execution Submitted Result -->
      <div v-if="currentStep === 3 && jobResult" class="wizard-step-pane">
        <KsFormSection title="3. 리밸런싱 OMS 작업 제출 완료">
          <div class="success-banner">
            <div class="icon">✅</div>
            <div class="text">
              <h3>리밸런싱 주문 작업이 대기열에 성공적으로 등록되었습니다.</h3>
              <p>OMS 배치 엔진에서 수량과 이탈율을 검증한 후 자동 체결 프로세스를 진행합니다.</p>
            </div>
          </div>
          <dl class="job-result-dl">
            <div class="row"><dt>Job ID</dt><dd><code>{{ jobResult.jobId }}</code></dd></div>
            <div class="row"><dt>제출 상태</dt><dd><KsStatusTag :value="jobResult.status" severity="info" /></dd></div>
            <div class="row"><dt>제출 시각</dt><dd>{{ jobResult.submittedAt }}</dd></div>
            <div class="row"><dt>총 매매 건수</dt><dd class="ks-financial-number">{{ formatQuantity(jobResult.estimatedTradeCount, 0) }} 건</dd></div>
            <div class="row"><dt>총 거래 규모</dt><dd class="ks-financial-number">{{ formatCurrency(jobResult.totalRebalanceValue, 'USD') }}</dd></div>
          </dl>
        </KsFormSection>
      </div>
    </div>
  </StepWizardPage>
</template>



<style scoped>
.ks-wizard-content {
  flex: 1;
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  gap: var(--ks-space-4);
}

.wizard-step-pane {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-4);
  flex: 1;
  min-height: 0;
}

.step1-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--ks-space-4);
  align-items: start;
}

@media (max-width: 1100px) {
  .step1-grid {
    grid-template-columns: 1fr;
  }
}

.target-card-row {
  display: flex;
  align-items: flex-end;
  gap: var(--ks-space-2);
}


.summary-bar {
  display: flex;
  gap: var(--ks-space-4);
  padding: var(--ks-space-2) var(--ks-space-3);
  background: var(--ks-color-canvas);
  border: 1px solid var(--ks-color-border);
  border-radius: var(--ks-radius-sm);
  font-size: var(--ks-font-body);
}

.threshold-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ks-space-4);
  margin-bottom: var(--ks-space-3);
}

.weight-total-badge {
  display: flex;
  align-items: center;
  gap: var(--ks-space-2);
  font-size: var(--ks-font-body);
  font-weight: 600;
}

.targets-container {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-2);
}

.target-card-row {
  display: flex;
  align-items: flex-end;
  gap: var(--ks-space-3);
}

.target-card-row > :first-child,
.target-card-row > :nth-child(2) {
  width: var(--ks-set-width-md, 260px);
}

.target-actions {
  display: flex;
  margin-top: var(--ks-space-2);
}

.simulation-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--ks-space-3);
}

.sim-item-card {
  padding: var(--ks-space-3);
  background: var(--ks-color-surface);
  border: 1px solid var(--ks-color-border-strong);
  border-radius: var(--ks-radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-2);
}

.sim-item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  border-bottom: 1px solid var(--ks-color-border);
  padding-bottom: 6px;
}

.sim-item-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--ks-font-caption);
}

.sim-item-body div {
  display: flex;
  justify-content: space-between;
}

.success-banner {
  display: flex;
  align-items: center;
  gap: var(--ks-space-3);
  padding: var(--ks-space-3);
  background: var(--ks-color-canvas);
  border: 1px solid var(--ks-color-success);
  border-radius: var(--ks-radius-md);
  margin-bottom: var(--ks-space-3);
}


.success-banner .icon {
  font-size: 28px;
}

.success-banner h3 {
  margin: 0 0 4px 0;
  font-size: var(--ks-font-section);
  color: var(--ks-color-success);
}

.success-banner p {
  margin: 0;
  font-size: var(--ks-font-body);
  color: var(--ks-color-text-muted);
}

.job-result-dl {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--ks-color-surface);
  padding: var(--ks-space-3);
  border: 1px solid var(--ks-color-border);
  border-radius: var(--ks-radius-md);
}

.job-result-dl .row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px dashed var(--ks-color-border);
}

.job-result-dl .row:last-child {
  border-bottom: none;
}

.job-result-dl dt {
  font-weight: 600;
  color: var(--ks-color-text-muted);
}

.job-result-dl dd {
  margin: 0;
  font-weight: 700;
}

.job-result-dl code {
  font-family: var(--ks-font-mono, monospace);
  background: var(--ks-color-canvas);
  padding: 2px 6px;
  border-radius: 3px;
  border: 1px solid var(--ks-color-border);
}
</style>

