<script setup lang="ts">
import { ref, computed, reactive, nextTick } from 'vue'
import SearchListCrudPage from '../../../shared/ui/screen-types/v2/SearchListCrudPage.vue'
import DataGridShell from '../../../shared/ui/DataGridShell.vue'
import {
  KsButton,
  KsSelect,
  KsStatusTag,
  KsTextField,
  KsFormSection
} from '../../../shared/ui/components'

import type { UiGridColumn, UiSelectOption } from '../../../shared/ui/adapter/contracts'
import type { StandardScreenState } from '../../../shared/ui/contracts/screenContract'

const screenState = ref<StandardScreenState>('READY')
const evidence = reactive({
  asOf: new Date().toISOString(),
  version: 'v60-SYS-01-Contract',
})

// Search & Filter State
const searchGroupQuery = ref('')
const searchUseYnFilter = ref('ALL')

const useYnOptions: UiSelectOption[] = [
  { label: '전체 상태', value: 'ALL' },
  { label: '사용 (Y)', value: 'Y' },
  { label: '미사용 (N)', value: 'N' },
]

// Mock Group Codes Data
interface GroupCode {
  groupCode: string
  groupName: string
  isSystem: boolean
  useYn: 'Y' | 'N'
  sortOrder: number
  codeCount: number
  description: string
  _isNew?: boolean
  _isModified?: boolean
}

interface CommonCode {
  code: string
  codeName: string
  value1: string
  value2: string
  sortOrder: number
  useYn: 'Y' | 'N'
  description: string
  _isNew?: boolean
  _isModified?: boolean
}

const mockGroupCodes = ref<GroupCode[]>([
  { groupCode: 'SYS_ROLE', groupName: '시스템 사용자 권한', isSystem: true, useYn: 'Y', sortOrder: 1, codeCount: 4, description: '시스템 관리자, 트레이더, 리서처, 데이터관리자 권한 코드' },
  { groupCode: 'ORDER_STATUS', groupName: 'OMS 주문 처리 상태', isSystem: true, useYn: 'Y', sortOrder: 2, codeCount: 5, description: 'OMS 주문 수신, 검증, 체결 완료, 거부, 취소 상태' },
  { groupCode: 'ASSET_TYPE', groupName: '포트폴리오 자산 유형', isSystem: false, useYn: 'Y', sortOrder: 3, codeCount: 3, description: '주식, ETF, 현금성 자산 구분' },
  { groupCode: 'REBALANCE_TYPE', groupName: '리밸런싱 실행 유형', isSystem: false, useYn: 'Y', sortOrder: 4, codeCount: 3, description: '정기 리밸런싱, 이탈 임계값 조절, 손절매 리밸런싱' },
  { groupCode: 'DQ_STATUS', groupName: '데이터 품질 검증 상태', isSystem: true, useYn: 'Y', sortOrder: 5, codeCount: 3, description: 'DQ 통과(PASSED), 격리(QUARANTINED), 대기(PENDING)' },
])

const mockChildCodesMap = reactive<Record<string, CommonCode[]>>({
  SYS_ROLE: [
    { code: 'ADMIN', codeName: '시스템 관리자 (Admin)', value1: 'ALL_ACCESS', value2: 'ROLE_ADMIN', sortOrder: 1, useYn: 'Y', description: '모든 시스템 관리 및 실행 권한' },
    { code: 'TRADER', codeName: '트레이더 (Trader)', value1: 'OMS_EXECUTE', value2: 'ROLE_TRADER', sortOrder: 2, useYn: 'Y', description: '리밸런싱 및 주문 제출 권한' },
    { code: 'RESEARCHER', codeName: '퀀트 리서처 (Researcher)', value1: 'MODEL_EVAL', value2: 'ROLE_QUANT', sortOrder: 3, useYn: 'Y', description: '매도 정책 시뮬레이션 권한' },
    { code: 'DATA_ADMIN', codeName: '데이터 관리자 (DataAdmin)', value1: 'INGEST_OPS', value2: 'ROLE_DATA', sortOrder: 4, useYn: 'Y', description: '시장 데이터 수집 배치 관리' },
  ],
  ORDER_STATUS: [
    { code: 'QUEUED', codeName: '대기 중 (Queued)', value1: '10', value2: 'INIT', sortOrder: 1, useYn: 'Y', description: 'OMS 대기열 등록 완료' },
    { code: 'SUBMITTED', codeName: '주문 제출 (Submitted)', value1: '20', value2: 'SENT', sortOrder: 2, useYn: 'Y', description: '증권사 KIS API 제출' },
    { code: 'EXECUTED', codeName: '체결 완료 (Executed)', value1: '30', value2: 'DONE', sortOrder: 3, useYn: 'Y', description: '전량 체결 완료' },
    { code: 'PARTIAL', codeName: '부분 체결 (Partial)', value1: '35', value2: 'PART', sortOrder: 4, useYn: 'Y', description: '일부 잔량 남음' },
    { code: 'REJECTED', codeName: '주문 거부 (Rejected)', value1: '90', value2: 'ERR', sortOrder: 5, useYn: 'Y', description: '이탈 한도 초과 또는 오류' },
  ],
  ASSET_TYPE: [
    { code: 'STOCK', codeName: '개별 주식 (Stock)', value1: 'EQ', value2: 'EQUITY', sortOrder: 1, useYn: 'Y', description: '국내외 개별 상장 주식' },
    { code: 'ETF', codeName: '상장지수펀드 (ETF)', value1: 'FUND', value2: 'INDEX', sortOrder: 2, useYn: 'Y', description: '지수 및 테마 ETF' },
    { code: 'CASH', codeName: '현금성 자산 (Cash)', value1: 'MONEY', value2: 'USD', sortOrder: 3, useYn: 'Y', description: '예수금 및 단기 채권' },
  ],
  REBALANCE_TYPE: [
    { code: 'PERIODIC', codeName: '정기 리밸런싱', value1: 'MONTHLY', value2: 'CALENDAR', sortOrder: 1, useYn: 'Y', description: '월간/분기 정기 주기 스케줄' },
    { code: 'DRIFT_TRIGGER', codeName: '임계값 이탈 리밸런싱', value1: 'BAND', value2: 'THRESHOLD', sortOrder: 2, useYn: 'Y', description: '목표 비중 3% 초과 이탈 시' },
    { code: 'STOP_LOSS', codeName: '손절매 리밸런싱', value1: 'RISK', value2: 'EXIT', sortOrder: 3, useYn: 'Y', description: '리스크 한도 초과 매도' },
  ],
  DQ_STATUS: [
    { code: 'PASSED', codeName: '정상 통과 (Passed)', value1: 'PASS', value2: 'OK', sortOrder: 1, useYn: 'Y', description: '결함률 0% 무결성 유지' },
    { code: 'QUARANTINED', codeName: '격리 조치 (Quarantined)', value1: 'BLOCK', value2: 'HOLD', sortOrder: 2, useYn: 'Y', description: '결함 발견으로 알고리즘 차단' },
    { code: 'PENDING', codeName: '검증 대기 (Pending)', value1: 'WAIT', value2: 'CALC', sortOrder: 3, useYn: 'Y', description: '배치 검증 수행 대기 중' },
  ]
})

// Selected Master & Detail State
const selectedGroupCode = ref<GroupCode>(mockGroupCodes.value[0])

// Active Search State (Applied on [🔍 조회] click or Enter key)
const activeSearchQuery = ref('')
const activeUseYnFilter = ref('ALL')

const handleGroupSearch = () => {
  activeSearchQuery.value = searchGroupQuery.value.trim()
  activeUseYnFilter.value = searchUseYnFilter.value

  nextTick(() => {
    if (filteredGroupCodes.value.length > 0) {
      selectedGroupCode.value = filteredGroupCodes.value[0]
    }
    masterGridRef.value?.redrawRows()
  })
}


const filteredGroupCodes = computed(() => {
  const query = (activeSearchQuery.value || searchGroupQuery.value).trim().toLowerCase()
  const useYn = activeUseYnFilter.value || searchUseYnFilter.value

  return mockGroupCodes.value.filter(g => {
    const matchesQuery = !query ||
      g.groupCode.toLowerCase().includes(query) ||
      g.groupName.toLowerCase().includes(query)
    const matchesUseYn = useYn === 'ALL' || g.useYn === useYn
    return matchesQuery && matchesUseYn
  })
})



const currentChildCodes = computed(() => {
  if (!selectedGroupCode.value) return []
  return mockChildCodesMap[selectedGroupCode.value.groupCode] || []
})

// Grids Columns (Auto-sized based on Math.max(header, content), capped by minWidth & maxWidth)
const groupColumns: UiGridColumn[] = [
  { field: 'groupCode', header: '그룹코드 ID', minWidth: 120, maxWidth: 220, flex: 2, editable: true },
  { field: 'groupName', header: '그룹명', minWidth: 140, maxWidth: 300, flex: 3, editable: true },
  { field: 'useYn', header: '사용여부', minWidth: 70, maxWidth: 100, flex: 1, editable: true },
  { field: 'codeCount', header: '코드 수', minWidth: 65, maxWidth: 110, flex: 1, formatter: v => `${v}개` }
]

const childColumns: UiGridColumn[] = [
  { field: 'code', header: '공통코드 ID', minWidth: 110, maxWidth: 200, flex: 2, editable: true },
  { field: 'codeName', header: '코드명', minWidth: 140, maxWidth: 320, flex: 3, editable: true },
  { field: 'value1', header: '속성값 1', minWidth: 85, maxWidth: 180, flex: 2, editable: true },
  { field: 'value2', header: '속성값 2', minWidth: 85, maxWidth: 180, flex: 2, editable: true },
  { field: 'sortOrder', header: '정렬', minWidth: 60, maxWidth: 90, flex: 1, editable: true },
  { field: 'useYn', header: '사용여부', minWidth: 70, maxWidth: 100, flex: 1, editable: true }
]


const masterGridRef = ref<{ focusRow: (rowIndex: number, colKey?: string) => void; redrawRows: () => void } | null>(null)
const detailGridRef = ref<{ focusRow: (rowIndex: number, colKey?: string) => void; redrawRows: () => void } | null>(null)

const selectGroup = (group: GroupCode) => {
  selectedGroupCode.value = group
}

// Top-Row Insertion Pattern (unshift / Index 0)
const addGroupRow = () => {
  searchGroupQuery.value = ''
  searchUseYnFilter.value = 'ALL'
  activeSearchQuery.value = ''
  activeUseYnFilter.value = 'ALL'

  const newGrp: GroupCode = {
    groupCode: `NEW_GRP_${mockGroupCodes.value.length + 1}`,
    groupName: '새 그룹명',
    isSystem: false,
    useYn: 'Y',
    sortOrder: 1,
    codeCount: 0,
    description: '그리드 최상단 신규 등록 그룹',
    _isNew: true
  }

  mockGroupCodes.value.unshift(newGrp)
  selectedGroupCode.value = newGrp

  nextTick(() => {
    masterGridRef.value?.focusRow(0, 'groupCode')
  })
}


const removeGroupRow = () => {
  if (!selectedGroupCode.value) {
    alert('삭제 또는 취소할 그룹코드를 선택하세요.')
    return
  }
  const idx = mockGroupCodes.value.findIndex(g => g.groupCode === selectedGroupCode.value.groupCode)
  if (idx === -1) return

  const target = mockGroupCodes.value[idx]
  if (target._isNew) {
    mockGroupCodes.value.splice(idx, 1)
    if (mockGroupCodes.value.length > 0) {
      selectedGroupCode.value = mockGroupCodes.value[0]
    }
    masterGridRef.value?.redrawRows()
    return
  }

  if (target.isSystem) {
    alert('시스템 SYSTEM 필수 그룹코드는 삭제할 수 없습니다.')
    return
  }

  if (confirm(`선택한 마스터 그룹코드 [${target.groupCode}] (${target.groupName})를 삭제하시겠습니까?`)) {
    delete mockChildCodesMap[target.groupCode]
    mockGroupCodes.value.splice(idx, 1)
    if (mockGroupCodes.value.length > 0) {
      selectedGroupCode.value = mockGroupCodes.value[0]
    }
    masterGridRef.value?.redrawRows()
  }
}

const saveMasterBatch = () => {
  mockGroupCodes.value = mockGroupCodes.value.map(row => {
    const copy = { ...row }
    delete copy._isNew
    delete copy._isModified
    return copy
  })

  nextTick(() => {
    masterGridRef.value?.redrawRows()
    alert(`마스터 그룹코드 ${mockGroupCodes.value.length}건이 성공적으로 저장되었습니다.`)
  })
}


// Inline Child Code Grid Editing Handlers (Top-Row Insertion)
const addGridRow = () => {
  const groupCodeKey = selectedGroupCode.value.groupCode
  if (!mockChildCodesMap[groupCodeKey]) {
    mockChildCodesMap[groupCodeKey] = reactive<CommonCode[]>([])
  }
  const list = mockChildCodesMap[groupCodeKey]

  const newRow: CommonCode = {
    code: `NEW_CODE_${list.length + 1}`,
    codeName: '새 코드명',
    value1: '',
    value2: '',
    sortOrder: 1,
    useYn: 'Y',
    description: '그리드 최상단 신규 등록 코드',
    _isNew: true
  }

  list.unshift(newRow)
  selectedGroupCode.value.codeCount = list.length

  nextTick(() => {
    try {
      detailGridRef.value?.focusRow?.(0, 'code')
    } catch (e) {
      console.warn('focusRow not available', e)
    }
  })
}

const removeGridRow = () => {
  const groupCodeKey = selectedGroupCode.value.groupCode
  const list = mockChildCodesMap[groupCodeKey] || []
  if (list.length === 0) {
    alert('삭제할 세부 코드가 없습니다.')
    return
  }

  const target = list[0]

  if (target._isNew) {
    list.shift()
    selectedGroupCode.value.codeCount = list.length
    detailGridRef.value?.redrawRows()
    return
  }

  if (confirm(`[${groupCodeKey}] 그룹의 세부 코드 [${target.code}] (${target.codeName})를 삭제하시겠습니까?`)) {
    list.shift()
    selectedGroupCode.value.codeCount = list.length
    detailGridRef.value?.redrawRows()
  }
}

const saveGridBatch = () => {
  if (!selectedGroupCode.value) return
  const groupCodeKey = selectedGroupCode.value.groupCode
  const list = mockChildCodesMap[groupCodeKey] || []

  // Save both master row changes and detail child code rows cleanly
  mockGroupCodes.value.forEach(row => {
    delete row._isNew
    delete row._isModified
  })

  list.forEach(row => {
    delete row._isNew
    delete row._isModified
  })

  selectedGroupCode.value.codeCount = list.length
  masterGridRef.value?.redrawRows()
  detailGridRef.value?.redrawRows()

  alert(`[${groupCodeKey}] 그룹 세부 공통코드 ${list.length}건 및 마스터 코드 변경사항이 성공적으로 저장되었습니다.`)
}


const handleClosePage = () => {
  if (confirm('현재 화면을 닫고 메인 워크스페이스로 이동하시겠습니까?')) {
    window.history.back()
  }
}

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

<template>
  <SearchListCrudPage
    title="시스템 공통코드 관리 (전면 그리드 인라인 편집)"
    subtitle="마스터 그룹코드와 세부 공통코드 모두 그리드 셀 직접 편집 및 행 추가/일괄 저장 방식으로 신속하게 관리합니다."
    :state="screenState"
    :evidence="evidence"
    :initial-ratio="50"
    storage-key="ks_sys_common_code_splitter_v50"
    @retry="handleRetry"
  >

    <!-- Dedicated KBX Page Command Bar Slot (Right-aligned, with Close button) -->
    <template #commandBar>
      <KsButton label="🔍 조회" variant="primary" @click="handleGroupSearch" />
      <KsButton label="💾 저장" variant="primary" @click="saveGridBatch" />
      <KsButton label="❌ 닫기" variant="secondary" @click="handleClosePage" />
    </template>



    <!-- Page Level Actions Header Slot -->
    <template #actions>
      <KsButton label="📤 엑셀 다운로드" variant="secondary" />
    </template>


    <!-- Master Content Area (Left: Group Code Grid Inline Editor & Search Filters bound together) -->
    <div class="ks-master-pane">
      <KsFormSection title="1. 마스터 그룹코드 그리드 (Inline Editor)">
        <template #actions>
          <KsButton label="➕ 그룹 행 추가" variant="secondary" @click="addGroupRow" />
          <KsButton label="🗑️ 그룹 행 삭제" variant="danger" @click="removeGroupRow" />
          <KsButton label="💾 그룹 일괄 저장" variant="secondary" @click="saveMasterBatch" />
        </template>

        <div class="ks-filter-bar">
          <KsTextField
            v-model="searchGroupQuery"
            label="그룹코드 검색"
            placeholder="그룹코드 ID 또는 그룹명..."
            class="ks-set-search"
            @keyup.enter="handleGroupSearch"
          />
          <KsSelect
            v-model="searchUseYnFilter"
            label="사용 여부"
            :options="useYnOptions"
            class="ks-set-select"
          />
        </div>



        <DataGridShell
          ref="masterGridRef"
          :rows="filteredGroupCodes"
          :columns="groupColumns"
          empty-message="조회 조건에 해당하는 그룹코드가 없습니다."
          height="100%"
          @row-selected="selectGroup"
        />
        <div class="group-select-bar">
          <span>선택된 그룹: <strong>[{{ selectedGroupCode.groupCode }}] {{ selectedGroupCode.groupName }}</strong></span>
          <KsStatusTag :value="selectedGroupCode.isSystem ? '시스템 SYSTEM' : '일반 USER'" :severity="selectedGroupCode.isSystem ? 'warning' : 'info'" />
        </div>
      </KsFormSection>
    </div>

    <!-- Detail Pane (Right: Inline Editable Child Code Grid Workstation) -->
    <template #detail>
      <div class="ks-detail-pane">
        <!-- Inline Child Code Grid Section -->
        <KsFormSection
          :title="`2. [${selectedGroupCode.groupCode}] 세부 공통코드 그리드 (Inline Editor)`"
          description="셀을 더블클릭하여 즉시 수정 후 상단 [💾 세부 코드 일괄 저장] 버튼을 누르세요."
        >
          <template #actions>
            <KsButton label="➕ 행 추가" variant="secondary" @click="addGridRow" />
            <KsButton label="🗑️ 행 삭제" variant="danger" @click="removeGridRow" />
            <KsButton label="💾 세부 코드 일괄 저장" variant="primary" @click="saveGridBatch" />
          </template>

          <DataGridShell
            ref="detailGridRef"
            :rows="currentChildCodes"
            :columns="childColumns"
            empty-message="그룹코드에 속한 세부 코드가 없습니다. ➕ 행 추가로 등록하세요."
            height="100%"
          />
        </KsFormSection>
      </div>
    </template>
  </SearchListCrudPage>
</template>

<style scoped>
.ks-master-pane,
.ks-detail-pane {
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-2);
  height: 100%;
  flex: 1;
  min-height: 0;
}

.ks-filter-bar {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--ks-space-3);
  padding: 6px 10px;
  background: var(--ks-color-surface);
  border: 1px solid var(--ks-color-border);
  border-radius: var(--ks-radius-sm);
  margin-bottom: 6px;
  flex-shrink: 0;
  box-sizing: border-box;
}

.ks-filter-bar :deep(.ks-text-field),
.ks-filter-bar :deep(.ks-select) {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  margin-bottom: 0;
}

.ks-filter-bar :deep(.ks-text-field__label),
.ks-filter-bar :deep(.ks-select__label) {
  margin-bottom: 0;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  flex-shrink: 0;
}

.ks-filter-bar :deep(.ks-text-field__container),
.ks-filter-bar :deep(.ks-select__container) {
  flex: 1;
}

.ks-set-search {
  flex: 2;
  min-width: 150px;
}

.ks-set-select {
  flex: 1;
  min-width: 110px;
}

.ks-search-btn {
  margin-left: auto;
  flex-shrink: 0;
}


.group-select-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  background: var(--ks-color-canvas);
  border: 1px solid var(--ks-color-border);
  border-radius: var(--ks-radius-sm);
  font-size: var(--ks-font-body);
  margin-top: 4px;
  flex-shrink: 0;
}
</style>
