<script setup lang="ts">
import type { BlockData } from '@vigilkids/section-core'

import { computed, ref } from 'vue'

const props = defineProps<{
  blockOrder: string[]
  blocks: Record<string, BlockData>
  editorMode?: boolean
  settings: Record<string, unknown>
}>()

const s = computed(() => props.settings)

interface ColumnDef {
  label: string
  min_width?: number
}

function parseJsonOrArray<T>(value: unknown): T[] {
  if (Array.isArray(value))
    return value as T[]
  if (typeof value === 'string') {
    try {
      const parsed = JSON.parse(value)
      if (Array.isArray(parsed))
        return parsed as T[]
    }
    catch {
      /* JSON 解析失败，返回空数组 */
    }
  }
  return []
}

const variant = computed(() => String(s.value.variant || 'default'))

const columns = computed<ColumnDef[]>(() => {
  const raw = parseJsonOrArray<ColumnDef | string>(s.value.columns)
  return raw.map(item => (typeof item === 'string' ? { label: item } : item))
})

const rows = computed(() =>
  props.blockOrder
    .filter(id => props.blocks[id]?.type === 'table-row')
    .map((id) => {
      const block = props.blocks[id]!
      return parseJsonOrArray<string>(block.settings.cells)
    }),
)

const expanded = ref(false)
</script>

<template>
<!-- blog-table: default -->
  <div v-if="variant === 'default'" class="blog-table-scroll">
    <div class="blog-table-wrapper">
      <table class="blog-table">
        <thead>
          <tr class="blog-table-header">
            <th
              v-for="(col, idx) in columns"
              :key="idx"
              :class="
                idx === columns.length - 1
                  ? 'blog-table-header-cell-last'
                  : 'blog-table-header-cell'
              "
            >
              {{ col.label }}
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, rowIdx) in rows" :key="rowIdx" class="blog-table-row">
            <td
              v-for="(cell, cellIdx) in row"
              :key="cellIdx"
              :class="
                cellIdx === 0
                  ? 'blog-table-cell-first'
                  : cellIdx === row.length - 1
                    ? 'blog-table-cell-last'
                    : 'blog-table-cell'
              "
              v-html="cell"
            />
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <!-- blog-table: collapsible -->
  <div v-else-if="variant === 'collapsible'" class="blog-table-scroll">
    <div class="blog-table-wrapper collapsible" :class="{ expanded }">
      <div
        class="blog-table-content"
        :class="{ expanded }"
      >
        <table class="blog-table">
          <thead>
            <tr class="blog-table-header">
              <th
                v-for="(col, idx) in columns"
                :key="idx"
                :class="
                  idx === columns.length - 1
                    ? 'blog-table-header-cell-last'
                    : 'blog-table-header-cell'
                "
              >
                {{ col.label }}
              </th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(row, rowIdx) in rows" :key="rowIdx" class="blog-table-row">
              <td
                v-for="(cell, cellIdx) in row"
                :key="cellIdx"
                :class="
                  cellIdx === 0
                    ? 'blog-table-cell-first'
                    : cellIdx === row.length - 1
                      ? 'blog-table-cell-last'
                      : 'blog-table-cell'
                "
                v-html="cell"
              />
            </tr>
          </tbody>
        </table>
      </div>
      <div class="blog-table-overlay">
        <button
          class="blog-table-toggle"
          type="button"
          aria-label="Toggle table"
          :aria-expanded="expanded"
          @click="expanded = !expanded"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
.blog-table-wrapper{border:1px solid #d4d4d4;border-radius:20px;font-size:14px;margin-top:40px;min-width:0;overflow-x:auto;text-align:center}.blog-table{border-collapse:collapse;min-width:800px;width:100%}.blog-table-header{background:#292929;color:#fff;font-size:18px}.blog-table-header-cell{border-right:1px solid #5e5e68;font-weight:600;padding:17px 16px}.blog-table-header-cell-last{font-size:14px;font-weight:600;padding:17px 16px}.blog-table-row{background:#fff;border-top:1px solid #d9d9d9;color:#000;font-weight:300;transition:background-color .2s ease}.blog-table-row:hover .blog-table-cell,.blog-table-row:hover .blog-table-cell-first,.blog-table-row:hover .blog-table-cell-last{background:#f7fff9}.blog-table-cell,.blog-table-cell-first{border-right:1px solid #d9d9d9;padding:17px 16px}.blog-table-cell-first{background:#f4f4f4;font-size:15px}.blog-table-cell-last{font-size:14px;padding:17px 16px}.blog-table-wrapper.collapsible{background:#fff;overflow:hidden;position:relative}.blog-table-content{max-height:500px;min-width:0;overflow-y:hidden;position:relative;transition:max-height .3s ease-in-out}.blog-table-content.expanded{max-height:3000px;padding-bottom:80px}.blog-table-overlay{background:linear-gradient(180deg,hsla(0,0%,100%,.72),#fff);bottom:0;height:80px;left:0;position:absolute;right:0;z-index:10}.blog-table-wrapper.collapsible.expanded .blog-table-overlay{background:transparent;bottom:0;height:80px;pointer-events:none}.blog-table-toggle{align-items:center;background:#fff;border:1px solid #d4d4d4;border-radius:50%;box-shadow:0 4px 14.1px 0 rgba(0,0,0,.13);cursor:pointer;display:flex;height:50px;justify-content:center;left:50%;margin-left:-25px;position:absolute;transform:translateY(-50%);transition:all .3s;width:50px;z-index:10}.blog-table-toggle:before{background-image:url(https://cdn.visiva.ai/visiva/library/general/image/2026/06/15/2458f67aa6069b33/arrow.down.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;content:"";display:block;height:20px;transition:transform .3s ease;width:20px}.blog-table-toggle:hover{background:#f2f4f3;border-color:#bfc7c2}.blog-table-wrapper.collapsible.expanded .blog-table-toggle{bottom:16px;pointer-events:auto;transform:none}.blog-table-wrapper.collapsible.expanded .blog-table-toggle:before{transform:rotate(180deg)}.blog-table :deep(a){color:#1fb04f;font-weight:400}
</style>
