<script setup lang="ts">
import { reactive, computed, ref, onMounted } from 'vue'
import BatchOperationsPageV2 from '../../../shared/ui/screen-types/v2/BatchOperationsPageV2.vue'
import DataGridShell from '../../../shared/ui/DataGridShell.vue'
import { KsButton, KsStatusTag } from '../../../shared/ui/components'
import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract'
import type { UiGridColumn } from '../../../shared/ui/adapter/contracts'
import { formatAsOf } from '../../../shared/formatters/financial'

// KBX T08 Governance Audit & Screen State
const screenState = ref<StandardScreenState>('READY')
const evidence = reactive({
  asOf: '2026-08-15T19:40:00Z',
  version: 'v60-T08-Contract',
})

// Mock Shadow Run Batch Jobs Data
const mockJobs = [
  {
    jobId: '893',
    modelId: '1',
    modelName: 'Hawkeye-Alpha v2.1',
    windowStart: '2024-01-02',
    windowEnd: '2025-08-14',
    tradingDays: 280,
    status: 'running',
    progress: 45,
    startedAt: '2026-08-14T09:00:00Z',
    errorMessage: null,
  },
  {
    jobId: '876',
    modelId: '2',
    modelName: 'Falcon-Beta v1.8',
    windowStart: '2024-01-02',
    windowEnd: '2025-07-15',
    tradingDays: 265,
    status: 'completed',
    progress: 100,
    startedAt: '2026-08-10T14:00:00Z',
    errorMessage: null,
  },
  {
    jobId: '812',
    modelId: '3',
    modelName: 'Gamma Arbitrage v3.0',
    windowStart: '2024-01-02',
    windowEnd: '2025-06-30',
    tradingDays: 250,
    status: 'failed',
    progress: 67,
    startedAt: '2026-08-08T08:00:00Z',
    errorMessage: 'Database connection timeout at day 168',
  },
]

const jobs = ref(mockJobs)

const filterModel = reactive({
  search: '',
  status: '',
})

onMounted(() => {
  screenState.value = 'LOADING'
  setTimeout(() => {
    screenState.value = 'READY'
  }, 300)
})

const filteredJobs = computed(() => {
  return jobs.value.filter(j => {
    const matchesSearch =
      j.modelName.toLowerCase().includes(filterModel.search.toLowerCase()) ||
      j.jobId.includes(filterModel.search)
    const matchesStatus = !filterModel.status || j.status === filterModel.status
    return matchesSearch && matchesStatus
  })
})

const shadowRunColumns: UiGridColumn[] = [
  { field: 'jobId', header: 'Job ID', minWidth: 90, flex: 1, formatter: value => `#${value}` },
  { field: 'modelName', header: 'Model Name', minWidth: 200, flex: 3 },
  { field: 'windowStart', header: 'Window Period', minWidth: 220, flex: 3, formatter: (val, row) => `${val} ~ ${(row as any)?.windowEnd ?? ''}` },
  { field: 'tradingDays', header: 'Days', minWidth: 70, flex: 1, formatter: val => `${val}d` },
  { field: 'status', header: 'Status', minWidth: 100, flex: 1, formatter: val => String(val).toUpperCase() },
  { field: 'progress', header: 'Progress', minWidth: 90, flex: 1, formatter: val => `${val}%` },
  { field: 'startedAt', header: 'Started At', minWidth: 160, flex: 2, formatter: val => val ? formatAsOf(String(val)) : '—' },
]

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

<template>
  <BatchOperationsPageV2
    title="Shadow Run 배치 운영 (Model Operation Shadow Run Queue)"
    subtitle="라이브 주문 제출 전 모델의 평가 및 워터마크 기반 배치 작업을 안전하게 모니터링합니다."
    :state="screenState"
    :evidence="evidence"
    @retry="handleRetry"
  >
    <template #filters>
      <section class="filters" aria-label="배치 작업 검색 및 필터">
        <input
          v-model="filterModel.search"
          placeholder="작업 ID 또는 모델명 검색..."
          class="input search-input"
          aria-label="배치 ID 및 모델명 검색"
          role="searchbox"
        />
        <select
          v-model="filterModel.status"
          class="input status-select"
          aria-label="배치 상태 필터"
        >
          <option value="">전체 상태</option>
          <option value="running">실행 중 (Running)</option>
          <option value="completed">완료 (Completed)</option>
          <option value="failed">실패 (Failed)</option>
        </select>
      </section>
    </template>

    <template #actions>
      <KsButton
        label="▶ 배치 실행"
        variant="primary"
        aria-label="신규 Shadow Run 트리거"
      />
    </template>

    <!-- Default Slot: Standardized Grid -->
    <DataGridShell
      :rows="filteredJobs"
      :columns="shadowRunColumns"
      empty-message="검색 조건에 맞는 배치 작업이 없습니다."
    />
  </BatchOperationsPageV2>
</template>

<style scoped>
.shadow-run-queue {
  padding: var(--spacing-5);
  max-width: 1200px;
  margin: 0 auto;
}

.skeleton-container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  margin-top: var(--spacing-4);
}

.error-content {
  text-align: center;
  padding: var(--spacing-4);
}

h1 {
  margin-bottom: var(--spacing-5);
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--spacing-4);
  margin-bottom: var(--spacing-5);
}

.stat {
  padding: var(--spacing-4);
  background: var(--color-background-secondary);
  border-radius: var(--border-radius-lg);
  border-left: var(--border-width-2) solid var(--color-border-secondary);
  transition: all var(--transition-base);
}

.stat:hover {
  box-shadow: var(--shadow-sm);
}

.stat-pending {
  border-left-color: var(--color-primary-500);
}

.stat-completed {
  border-left-color: var(--color-success-500);
}

.stat-failed {
  border-left-color: var(--color-danger-500);
}

.stat .label {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
  margin-bottom: var(--spacing-2);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.stat .value {
  display: block;
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.filters {
  display: flex;
  align-items: center;
  gap: var(--ks-space-3);
  width: 100%;
}

.search-input {
  min-width: 200px;
  max-width: 350px;
  width: 100%;
}

.status-select {
  min-width: 150px;
}

.input:hover {
  border-color: var(--color-input-hover);
}

.input:focus {
  outline: none;
  border-color: var(--ks-color-action);
  box-shadow: 0 0 0 2px var(--ks-color-action);
}

.empty-state {
  text-align: center;
  padding: var(--spacing-8);
  color: var(--color-text-tertiary);
}

.jobs-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}

.job-card {
  padding: var(--spacing-4);
  border: var(--border-width-1) solid var(--color-border-primary);
  border-left: var(--border-width-2) solid;
  border-radius: var(--border-radius-lg);
  background: var(--color-background-primary);
  transition: all var(--transition-base);
}

.job-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-border-secondary);
}

.job-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--spacing-3);
  gap: var(--spacing-3);
}

.job-header h3 {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  flex: 1;
}

.job-meta {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--spacing-3);
  margin-bottom: var(--spacing-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.job-meta div {
  display: flex;
  justify-content: space-between;
}

.job-meta code {
  background: var(--color-background-secondary);
  padding: 2px 6px;
  border-radius: var(--border-radius-base);
  font-family: var(--font-mono);
  color: var(--color-text-primary);
  font-size: var(--font-size-xs);
}

.progress-container {
  position: relative;
  height: 24px;
  background: var(--color-background-secondary);
  border-radius: var(--border-radius-base);
  overflow: hidden;
  margin-bottom: var(--spacing-3);
  border: var(--border-width-1) solid var(--color-border-secondary);
}

.progress-bar {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  transition: width var(--transition-slow);
  opacity: 0.9;
}

.progress-text {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.error-message {
  padding: var(--spacing-2) var(--spacing-3);
  background: var(--color-danger-50);
  color: var(--color-danger-700);
  border-left: var(--border-width-2) solid var(--color-danger-500);
  border-radius: var(--border-radius-base);
  font-size: var(--font-size-xs);
  margin-bottom: var(--spacing-3);
}

.status-badge {
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--border-radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: white;
  white-space: nowrap;
}

.actions {
  display: flex;
  gap: var(--spacing-2);
  justify-content: flex-end;
}

.btn {
  padding: var(--spacing-2) var(--spacing-3);
  border: var(--border-width-1) solid var(--color-border-primary);
  border-radius: var(--border-radius-base);
  background: var(--color-background-secondary);
  color: var(--color-text-primary);
  cursor: pointer;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  transition: all var(--transition-fast);
  font-family: var(--font-sans);
}

.btn:hover:not(:disabled) {
  background: var(--color-background-hover);
  border-color: var(--color-border-secondary);
}

.btn:active:not(:disabled) {
  background: var(--color-background-active);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-secondary {
  background: var(--color-background-secondary);
  color: var(--color-text-primary);
}

.btn-secondary:hover:not(:disabled) {
  background: var(--color-background-hover);
}

.btn-danger {
  background: var(--color-danger-50);
  color: var(--color-danger-700);
  border-color: var(--color-danger-200);
}

.btn-danger:hover:not(:disabled) {
  background: var(--color-danger-100);
  border-color: var(--color-danger-300);
}

@media (max-width: 768px) {
  .stats {
    grid-template-columns: repeat(2, 1fr);
  }

  .job-meta {
    grid-template-columns: 1fr;
  }

  .filters {
    grid-template-columns: 1fr;
  }

  .job-header {
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>
