<template>
  <div class="demo-block">
    <div class="demo-block__header">
      <h3 class="demo-block__title">{{ title }}</h3>
      <p v-if="description" class="demo-block__description">{{ description }}</p>
    </div>
    
    <div class="demo-block__preview">
      <slot />
    </div>
    
    <div class="demo-block__actions">
      <button 
        class="demo-block__action-btn"
        title="复制代码"
        @click="copyCode"
      >
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
          <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
        </svg>
        <span v-if="copied" class="copied-tip">已复制!</span>
      </button>
      <button 
        class="demo-block__action-btn"
        :class="{ 'demo-block__action-btn--active': showCode }"
        title="查看代码"
        @click="showCode = !showCode"
      >
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <polyline points="16,18 22,12 16,6"></polyline>
          <polyline points="8,6 2,12 8,18"></polyline>
        </svg>
      </button>
    </div>
    
    <transition name="slide-fade">
      <div v-show="showCode" class="demo-block__code">
        <pre><code v-html="highlightedCode"></code></pre>
      </div>
    </transition>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
// @ts-ignore - highlight.js types
import hljs from 'highlight.js/lib/core';
// @ts-ignore
import xml from 'highlight.js/lib/languages/xml';
// @ts-ignore
import javascript from 'highlight.js/lib/languages/javascript';
// @ts-ignore
import typescript from 'highlight.js/lib/languages/typescript';
// @ts-ignore
import scss from 'highlight.js/lib/languages/scss';
// @ts-ignore
import css from 'highlight.js/lib/languages/css';

// Register languages
hljs.registerLanguage('xml', xml);
hljs.registerLanguage('html', xml);
hljs.registerLanguage('vue', xml);
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('scss', scss);
hljs.registerLanguage('css', css);

export default defineComponent({
  name: 'DemoBlock',
  props: {
    title: {
      type: String,
      required: true,
    },
    description: {
      type: String,
      default: '',
    },
    code: {
      type: String,
      required: true,
    },
    language: {
      type: String,
      default: 'vue',
    },
  },
  setup(props) {
    const showCode = ref(false);
    const copied = ref(false);

    const highlightedCode = computed(() => {
      try {
        // Try to highlight with the specified language
        const result = hljs.highlight(props.code, { 
          language: props.language,
          ignoreIllegals: true,
        });
        return result.value;
      } catch {
        // Fallback to auto-detection
        try {
          const result = hljs.highlightAuto(props.code);
          return result.value;
        } catch {
          // If all fails, return escaped code
          return props.code
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
        }
      }
    });

    async function copyCode() {
      try {
        await navigator.clipboard.writeText(props.code);
        copied.value = true;
        setTimeout(() => {
          copied.value = false;
        }, 2000);
      } catch (err) {
        console.error('Failed to copy code:', err);
      }
    }

    return {
      showCode,
      copied,
      copyCode,
      highlightedCode,
    };
  },
});
</script>

<style scoped lang="scss">
.demo-block {
  margin-bottom: 24px;
  border: 1px solid var(--stroke-color-primary, #e4e7ed);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-color-operate, #fff);
  transition: box-shadow 0.3s ease;
  max-width: 100%;

  &:hover {
    box-shadow: 0 4px 12px var(--shadow-color, rgba(0, 0, 0, 0.08));
  }

  @media (max-width: 768px) {
    margin-bottom: 16px;
    border-radius: 6px;
  }
}

.demo-block__header {
  padding: 16px 20px 0;

  @media (max-width: 768px) {
    padding: 12px 16px 0;
  }
}

.demo-block__title {
  margin: 0 0 8px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-color-primary, #303133);
}

.demo-block__description {
  margin: 0;
  font-size: 14px;
  color: var(--text-color-secondary, #606266);
  line-height: 1.6;
}

.demo-block__preview {
  padding: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  overflow-x: auto;
  max-width: 100%;

  @media (max-width: 768px) {
    padding: 16px;
    gap: 8px;
  }
}

.demo-block__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 8px 16px;
  border-top: 1px solid var(--stroke-color-secondary, #ebeef5);
  background: var(--bg-color-operate, #fff);
}

.demo-block__action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--text-color-tertiary, #909399);
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    color: var(--text-color-link, #409eff);
    background: var(--list-color-hover, rgba(64, 158, 255, 0.1));
  }

  &--active {
    color: var(--text-color-link, #409eff);
    background: var(--list-color-hover, rgba(64, 158, 255, 0.1));
  }

  .copied-tip {
    position: absolute;
    top: -30px;
    left: 50%;
    transform: translateX(-50%);
    padding: 4px 8px;
    font-size: 12px;
    color: #fff;
    background: var(--uikit-color-black-2, #333);
    border-radius: 4px;
    white-space: nowrap;
  }
}

.demo-block__code {
  border-top: 1px solid var(--stroke-color-secondary, #ebeef5);
  background: var(--bg-color-function, #fafafa);
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;

  pre {
    margin: 0;
    padding: 16px 20px;
    font-size: 13px;
    line-height: 1.6;
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
    overflow-x: auto;
    max-width: 100%;

    @media (max-width: 768px) {
      padding: 12px 16px;
      font-size: 12px;
    }
  }

  code {
    color: var(--text-color-primary, #303133);
    white-space: pre;
    display: block;
    word-break: break-all;
    overflow-wrap: break-word;

    // Highlight.js syntax highlighting colors
    :deep(.hljs-comment),
    :deep(.hljs-quote) {
      color: #6a737d;
      font-style: italic;
    }

    :deep(.hljs-keyword),
    :deep(.hljs-selector-tag),
    :deep(.hljs-addition) {
      color: #d73a49;
    }

    :deep(.hljs-number),
    :deep(.hljs-string),
    :deep(.hljs-meta .hljs-meta-string),
    :deep(.hljs-literal),
    :deep(.hljs-doctag),
    :deep(.hljs-regexp) {
      color: #22863a;
    }

    :deep(.hljs-title),
    :deep(.hljs-section),
    :deep(.hljs-name),
    :deep(.hljs-selector-id),
    :deep(.hljs-selector-class) {
      color: #6f42c1;
    }

    :deep(.hljs-attribute),
    :deep(.hljs-attr),
    :deep(.hljs-variable),
    :deep(.hljs-template-variable),
    :deep(.hljs-class .hljs-title),
    :deep(.hljs-type) {
      color: #005cc5;
    }

    :deep(.hljs-symbol),
    :deep(.hljs-bullet),
    :deep(.hljs-subst),
    :deep(.hljs-meta),
    :deep(.hljs-meta .hljs-keyword),
    :deep(.hljs-selector-attr),
    :deep(.hljs-selector-pseudo),
    :deep(.hljs-link) {
      color: #e36209;
    }

    :deep(.hljs-built_in),
    :deep(.hljs-deletion) {
      color: #b31d28;
    }

    :deep(.hljs-tag) {
      color: #22863a;
    }

    :deep(.hljs-tag .hljs-name) {
      color: #22863a;
    }

    :deep(.hljs-tag .hljs-attr) {
      color: #6f42c1;
    }

    :deep(.hljs-emphasis) {
      font-style: italic;
    }

    :deep(.hljs-strong) {
      font-weight: bold;
    }
  }
}

// Transition
.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.3s ease;
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  opacity: 0;
  max-height: 0;
}

.slide-fade-enter-to,
.slide-fade-leave-from {
  opacity: 1;
  max-height: 500px;
}
</style>
