<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import ElXMarkdown from 'vue-element-plus-x/es/XMarkdown/index.js';

import { $t } from '@easyflow/locales';

import { ElEmpty, ElSkeleton, ElTag } from 'element-plus';

import {
  markdownRenderProps,
  resolveMarkdownContent,
} from '#/views/ai/documentCollection/markdown-content';

interface SourceRange {
  end: number;
  start: number;
}

interface ChunkItem {
  answer?: string;
  charCount?: number;
  chunkId?: string;
  chunkType?: string;
  content?: string;
  headingPath?: string[];
  options?: Record<string, any>;
  partNo?: number;
  partTotal?: number;
  question?: string;
  renderMarkdown?: string;
  sourceLabel?: string;
  sourceRanges?: SourceRange[];
  tokenEstimate?: number;
  warnings?: string[];
}

interface PreviewItem {
  analysis?: {
    normalizedContent?: string;
    recommendedStrategyLabel?: string;
  };
  chunks?: ChunkItem[];
  fileName: string;
  normalizedContent?: string;
  previewSessionId: string;
  strategyLabel?: string;
  totalChunks?: number;
  totalWarnings?: number;
}

const props = withDefaults(
  defineProps<{
    activeChunkId?: string;
    loading?: boolean;
    lockedChunkId?: string;
    previewItems?: PreviewItem[];
  }>(),
  {
    activeChunkId: '',
    loading: false,
    lockedChunkId: '',
    previewItems: () => [],
  },
);

const emits = defineEmits(['previewSessionChange']);

const activeFile = ref('');

const previewItems = computed(() => props.previewItems ?? []);
const currentPreview = computed(
  () =>
    previewItems.value.find(
      (item) => item.previewSessionId === activeFile.value,
    ) || previewItems.value[0],
);

watch(
  previewItems,
  (items) => {
    if (items.length === 0) {
      activeFile.value = '';
      emits('previewSessionChange', '');
      return;
    }
    if (!items.some((item) => item.previewSessionId === activeFile.value)) {
      activeFile.value = items[0]?.previewSessionId || '';
    }
  },
  { immediate: true },
);

watch(
  currentPreview,
  (preview) => {
    emits('previewSessionChange', preview?.previewSessionId || '');
  },
  { immediate: true },
);

const isLockedChunk = (chunk: ChunkItem) =>
  String(chunk.chunkId || '') === String(props.lockedChunkId || '');

const isActiveChunk = (chunk: ChunkItem) =>
  String(chunk.chunkId || '') === String(props.activeChunkId || '');
</script>

<template>
  <div class="preview-shell">
    <div class="preview-shell__header">
      <div>
        <div class="preview-shell__title">
          {{ $t('documentCollection.importDoc.previewPaneTitle') }}
        </div>
      </div>

      <div v-if="currentPreview" class="preview-shell__summary">
        <ElTag effect="plain" round>
          {{ currentPreview.strategyLabel || '-' }}
        </ElTag>
        <ElTag effect="plain" round>
          {{ currentPreview.totalChunks || 0 }}
          {{ $t('documentCollection.importDoc.chunkCount') }}
        </ElTag>
      </div>
    </div>

    <div
      v-if="loading && previewItems.length === 0"
      class="preview-shell__loading"
    >
      <ElSkeleton animated :rows="7" />
    </div>

    <ElEmpty
      v-else-if="previewItems.length === 0"
      :description="$t('documentCollection.importDoc.previewEmpty')"
    />

    <div v-else class="preview-shell__content">
      <div class="chunk-list">
        <div
          v-for="chunk in currentPreview?.chunks || []"
          :key="chunk.chunkId"
          class="chunk-card"
          :class="{
            'chunk-card--active': isActiveChunk(chunk),
            'chunk-card--locked': isLockedChunk(chunk),
          }"
        >
          <div class="chunk-card__header">
            <div class="chunk-card__main">
              <div class="chunk-card__title-row">
                <span class="chunk-card__title">
                  {{ chunk.sourceLabel || chunk.chunkId }}
                </span>
                <span v-if="isLockedChunk(chunk)" class="chunk-card__state">
                  {{ $t('documentCollection.importDoc.lockedState') }}
                </span>
              </div>
              <div
                v-if="chunk.headingPath && chunk.headingPath.length > 0"
                class="chunk-card__path"
              >
                {{ chunk.headingPath.join(' / ') }}
              </div>
            </div>

            <div class="chunk-card__meta">
              <ElTag effect="plain" round>
                {{ chunk.chunkType || '-' }}
              </ElTag>
              <ElTag effect="plain" round>
                {{ chunk.charCount || 0 }} / {{ chunk.tokenEstimate || 0 }}
              </ElTag>
              <ElTag
                v-if="(chunk.partTotal || 1) > 1"
                effect="plain"
                round
                type="warning"
              >
                {{ chunk.partNo }}/{{ chunk.partTotal }}
              </ElTag>
            </div>
          </div>

          <div v-if="chunk.chunkType === 'qa_pair'" class="qa-block">
            <div class="qa-block__item">
              <span class="qa-block__label">Q</span>
              <div class="qa-block__text">
                <ElXMarkdown
                  :markdown="resolveMarkdownContent(chunk.question)"
                  :allow-html="markdownRenderProps.allowHtml"
                  :sanitize="markdownRenderProps.sanitize"
                />
              </div>
            </div>
            <div class="qa-block__item">
              <span class="qa-block__label">A</span>
              <div class="qa-block__text">
                <ElXMarkdown
                  :markdown="resolveMarkdownContent(chunk.answer)"
                  :allow-html="markdownRenderProps.allowHtml"
                  :sanitize="markdownRenderProps.sanitize"
                />
              </div>
            </div>
          </div>

          <div
            v-if="resolveMarkdownContent(chunk.renderMarkdown || chunk.content)"
            class="chunk-card__content chunk-card__content--markdown"
          >
            <ElXMarkdown
              :markdown="
                resolveMarkdownContent(chunk.renderMarkdown || chunk.content)
              "
              :allow-html="markdownRenderProps.allowHtml"
              :sanitize="markdownRenderProps.sanitize"
            />
          </div>

          <div
            v-if="chunk.warnings && chunk.warnings.length > 0"
            class="chunk-card__warnings"
          >
            <ElTag
              v-for="warning in chunk.warnings"
              :key="warning"
              effect="plain"
              round
              type="warning"
            >
              {{ warning }}
            </ElTag>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.preview-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  padding-top: 4px;
}

.preview-shell__header {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: flex-start;
  justify-content: space-between;
  padding-bottom: 10px;
}

.preview-shell__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--el-text-color-secondary);
}

.preview-shell__summary {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.preview-shell__loading {
  padding-top: 12px;
}

.preview-shell__content {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding-top: 4px;
}

.chunk-list {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  padding-right: 4px;
  overflow: auto;
}

.chunk-card {
  padding: 15px 16px 14px;
  cursor: pointer;
  user-select: none;
  background: var(--el-fill-color-blank);
  background: color-mix(in srgb, var(--el-fill-color-blank) 92%, white);
  border: 1px solid rgb(15 23 42 / 7%);
  border-radius: 14px;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease,
    box-shadow 0.18s ease,
    transform 0.18s ease;
}

.chunk-card:hover {
  background: var(--el-fill-color-blank);
  border-color: rgb(11 111 211 / 22%);
  box-shadow: 0 10px 20px rgb(15 23 42 / 6%);
  transform: translateY(-1px);
}

.chunk-card--active {
  border-color: rgb(22 111 211 / 26%);
  background: linear-gradient(180deg, rgb(242 248 255 / 96%), #fff 100%);
}

.chunk-card--locked {
  border-color: rgb(11 111 211 / 34%);
  box-shadow: inset 0 0 0 1px rgb(11 111 211 / 10%);
}

.chunk-card__header {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  justify-content: space-between;
}

.chunk-card__main {
  min-width: 0;
}

.chunk-card__title-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.chunk-card__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.chunk-card__state {
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 500;
  color: #0b6fd3;
  background: rgb(11 111 211 / 8%);
  border-radius: 999px;
}

.chunk-card__path {
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--el-text-color-secondary);
}

.chunk-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.chunk-card__content {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.75;
  color: var(--el-text-color-regular);
}

.chunk-card__content--markdown {
  min-width: 0;
}

.chunk-card__content--markdown :deep(.markdown-body) {
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  background: transparent;
}

.chunk-card__content--markdown :deep(.markdown-body > :first-child) {
  margin-top: 0;
}

.chunk-card__content--markdown :deep(.markdown-body > :last-child) {
  margin-bottom: 0;
}

.chunk-card__content--markdown :deep(*) {
  overflow-wrap: anywhere;
}

.chunk-card__content--markdown :deep(p) {
  margin: 0 0 10px;
}

.chunk-card__content--markdown :deep(p:last-child) {
  margin-bottom: 0;
}

.chunk-card__content--markdown :deep(h1),
.chunk-card__content--markdown :deep(h2),
.chunk-card__content--markdown :deep(h3),
.chunk-card__content--markdown :deep(h4),
.chunk-card__content--markdown :deep(h5),
.chunk-card__content--markdown :deep(h6) {
  margin: 14px 0 10px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--el-text-color-primary);
}

.chunk-card__content--markdown :deep(h1:first-child),
.chunk-card__content--markdown :deep(h2:first-child),
.chunk-card__content--markdown :deep(h3:first-child),
.chunk-card__content--markdown :deep(h4:first-child),
.chunk-card__content--markdown :deep(h5:first-child),
.chunk-card__content--markdown :deep(h6:first-child) {
  margin-top: 0;
}

.chunk-card__content--markdown :deep(ul),
.chunk-card__content--markdown :deep(ol) {
  padding-left: 20px;
  margin: 0 0 12px;
}

.chunk-card__content--markdown :deep(li + li) {
  margin-top: 4px;
}

.chunk-card__content--markdown :deep(a) {
  color: var(--el-color-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.chunk-card__content--markdown :deep(img) {
  display: block;
  max-width: min(100%, 520px);
  height: auto;
  margin: 12px 0;
  border: 1px solid rgb(15 23 42 / 8%);
  border-radius: 12px;
  box-shadow: 0 10px 24px rgb(15 23 42 / 8%);
}

.chunk-card__content--markdown :deep(table) {
  width: 100%;
  margin: 12px 0;
  overflow: hidden;
  border-collapse: collapse;
  background: rgb(255 255 255 / 92%);
  border: 1px solid rgb(15 23 42 / 8%);
  border-radius: 12px;
}

.chunk-card__content--markdown :deep(th),
.chunk-card__content--markdown :deep(td) {
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
  border: 1px solid rgb(15 23 42 / 8%);
}

.chunk-card__content--markdown :deep(th) {
  font-weight: 600;
  color: var(--el-text-color-primary);
  background: rgb(37 99 235 / 4%);
}

.chunk-card__content--markdown :deep(pre) {
  max-width: 100%;
  padding: 12px 14px;
  overflow: auto;
  background: rgb(15 23 42 / 4%);
  border: 1px solid rgb(15 23 42 / 6%);
  border-radius: 12px;
}

.chunk-card__content--markdown :deep(blockquote) {
  padding-left: 12px;
  margin: 12px 0;
  color: var(--el-text-color-secondary);
  border-left: 3px solid rgb(37 99 235 / 24%);
}

.chunk-card__warnings {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.qa-block {
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  margin-top: 14px;
  background: rgb(15 23 42 / 3%);
  border-radius: 12px;
}

.qa-block__item {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: 8px;
  align-items: start;
}

.qa-block__label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  font-size: 12px;
  font-weight: 600;
  color: #0b6fd3;
  background: rgb(11 111 211 / 8%);
  border-radius: 999px;
}

.qa-block__text {
  min-width: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--el-text-color-regular);
}

.qa-block__text :deep(.markdown-body) {
  font-size: inherit;
  line-height: inherit;
  background: transparent;
}

.qa-block__text :deep(.markdown-body > :first-child) {
  margin-top: 0;
}

.qa-block__text :deep(.markdown-body > :last-child) {
  margin-bottom: 0;
}

.qa-block__text :deep(img) {
  display: block;
  max-width: min(100%, 420px);
  height: auto;
  margin: 10px 0;
  border-radius: 10px;
}

@media (max-width: 960px) {
  .preview-shell__header,
  .chunk-card__header {
    flex-direction: column;
  }

  .chunk-card__meta {
    justify-content: flex-start;
  }
}
</style>
