<!-- 剧本分析结果组件，负责按业务分类展示结构化分析内容。 -->
<script setup lang="ts">
import { computed, ref } from "vue";
import { BookOpenText, CircleX, Clapperboard, ListChecks, LoaderCircle, Tags, Target, Users, Zap } from "@/icons";
import type { ScriptAnalysisCharacter, ScriptAnalysisResult } from "@/api/creative";

const props = defineProps<{
  result?: ScriptAnalysisResult;
  characters?: ScriptAnalysisCharacter[];
  status?: string;
  message?: string;
}>();

const active = ref("tags");
const categories = computed(() => [
  { key: "tags", label: "标签", title: "标签", icon: Tags },
  { key: "selling", label: "看点", title: "看点卖点", icon: Target },
  { key: "story", label: "剧情", title: "剧情结构", icon: BookOpenText },
  { key: "characters", label: "角色", title: "角色库", icon: Users },
  { key: "opening", label: "开篇", title: "黄金三秒", icon: Zap },
  { key: "hooks", label: "钩子", title: "单集钩子", icon: Clapperboard },
  ...(props.result?.custom_analysis?.length || props.result?.unmatched_objectives?.length
    ? [{ key: "custom", label: "其他", title: "其他分析", icon: ListChecks }]
    : []),
]);
const hasResult = computed(() => props.status === "succeeded" && Boolean(Object.keys(props.result || {}).length));
const analysisCharacters = computed(() => props.characters || []);
</script>

<template>
  <article class="analysis-result">
    <header class="analysis-result__header">
      <strong>分析结果</strong>
      <span
        v-if="status === 'queued' || status === 'running'"
        class="analysis-state is-running"
      >
        {{ message || "正在分析剧本" }}
      </span>
      <span
        v-else-if="status === 'failed'"
        class="analysis-state is-failed"
      >
        分析失败
      </span>
      <span
        v-else-if="hasResult"
        class="analysis-state"
        >已完成</span
      >
    </header>

    <template v-if="hasResult">
      <nav class="analysis-categories">
        <button
          v-for="category in categories"
          :key="category.key"
          type="button"
          :class="{ active: active === category.key }"
          :title="category.title"
          @click="active = category.key"
        >
          <component
            :is="category.icon"
            :size="16"
          />
          <span>{{ category.label }}</span>
        </button>
      </nav>

      <div class="analysis-content">
        <section
          v-if="active === 'tags'"
          class="result-stack tag-section-grid"
        >
          <div class="result-block">
            <h3>短剧标签</h3>
            <div class="tag-list">
              <span
                v-for="tag in result?.tags?.drama_tags || []"
                :key="tag"
                >{{ tag }}</span
              >
              <p
                v-if="!result?.tags?.drama_tags?.length"
                class="empty-copy"
              >
                暂无标签
              </p>
            </div>
          </div>
          <div class="result-block">
            <h3>适用场景标签</h3>
            <div class="tag-list scene-tags">
              <span
                v-for="tag in result?.tags?.applicable_scene_tags || []"
                :key="tag"
                >{{ tag }}</span
              >
              <p
                v-if="!result?.tags?.applicable_scene_tags?.length"
                class="empty-copy"
              >
                暂无适用场景标签
              </p>
            </div>
          </div>
        </section>

        <section
          v-else-if="active === 'selling'"
          class="result-stack selling-layout"
        >
          <div class="summary-card">
            <span>一句话总结</span>
            <p>{{ result?.selling_point?.summary || "暂无总结" }}</p>
          </div>
          <div class="highlight-list content-card-grid">
            <article
              v-for="(item, index) in result?.selling_point?.highlights || []"
              :key="`${item.type}-${index}`"
            >
              <span>{{ item.type }}</span>
              <p>{{ item.content }}</p>
            </article>
            <p
              v-if="!result?.selling_point?.highlights?.length"
              class="empty-copy"
            >
              暂无核心看点
            </p>
          </div>
        </section>

        <section
          v-else-if="active === 'story'"
          class="result-stack"
        >
          <div class="result-block prose-block">
            <h3>短剧简介</h3>
            <p>{{ result?.story_structure?.synopsis || "暂无简介" }}</p>
          </div>
          <div class="result-block">
            <h3>故事大纲</h3>
            <ol class="outline-list">
              <li
                v-for="(item, index) in result?.story_structure?.story_outline || []"
                :key="index"
              >
                {{ item }}
              </li>
            </ol>
          </div>
          <div class="result-block">
            <h3>情绪大纲</h3>
            <div class="emotion-list content-card-grid">
              <article
                v-for="(item, index) in result?.story_structure?.emotion_outline || []"
                :key="index"
              >
                <header>
                  <strong>{{ item.stage }}</strong
                  ><span>{{ item.emotion }}</span>
                </header>
                <p>{{ item.description }}</p>
              </article>
            </div>
          </div>
          <div class="result-block">
            <h3>分集大纲</h3>
            <div class="episode-list content-card-grid">
              <article
                v-for="item in result?.story_structure?.episode_outlines || []"
                :key="item.episode_no"
              >
                <header>
                  <strong>第 {{ item.episode_no }} 集</strong><span>{{ item.title }}</span>
                </header>
                <p>{{ item.outline }}</p>
                <small v-if="item.emotion">情绪：{{ item.emotion }}</small>
              </article>
            </div>
          </div>
        </section>

        <section
          v-else-if="active === 'characters'"
          class="result-stack"
        >
          <div class="result-block">
            <div class="character-list content-card-grid">
              <article
                v-for="character in analysisCharacters"
                :key="character.id"
              >
                <header>
                  <strong>{{ character.name }}</strong
                  ><span>{{ character.faction }}</span>
                </header>
                <p>{{ character.biography }}</p>
                <dl>
                  <template v-if="character.motivation"
                    ><dt>核心动机</dt>
                    <dd>{{ character.motivation }}</dd></template
                  >
                  <template v-if="character.relationship"
                    ><dt>人物关系</dt>
                    <dd>{{ character.relationship }}</dd></template
                  >
                </dl>
              </article>
              <p
                v-if="!analysisCharacters.length"
                class="empty-copy"
              >
                暂无人物小传
              </p>
            </div>
          </div>
        </section>

        <section
          v-else-if="active === 'opening'"
          class="result-stack"
        >
          <div class="opening-grid">
            <article>
              <span>开篇第一个画面</span>
              <p>{{ result?.opening_hook?.first_scene || "暂无" }}</p>
            </article>
            <article>
              <span>第一句台词</span>
              <p>{{ result?.opening_hook?.first_line || "暂无" }}</p>
            </article>
          </div>
          <div class="result-block">
            <h3>抓眼方式</h3>
            <div class="tag-list">
              <span
                v-for="method in result?.opening_hook?.attention_methods || []"
                :key="method"
                >{{ method }}</span
              >
            </div>
          </div>
          <div class="result-block prose-block">
            <h3>分析</h3>
            <p>{{ result?.opening_hook?.analysis || "暂无分析" }}</p>
          </div>
          <div
            v-if="result?.opening_hook?.optimization"
            class="result-block prose-block"
          >
            <h3>优化建议</h3>
            <p>{{ result.opening_hook.optimization }}</p>
          </div>
        </section>

        <section
          v-else-if="active === 'hooks'"
          class="result-stack"
        >
          <div class="result-block">
            <h3>前十集逐集钩子</h3>
            <div class="hook-list">
              <article
                v-for="item in result?.episode_hooks || []"
                :key="item.episode_no"
              >
                <div class="hook-number">{{ item.episode_no }}</div>
                <div>
                  <header>
                    <strong>第 {{ item.episode_no }} 集</strong><span>{{ item.hook_type }}</span>
                  </header>
                  <p>{{ item.hook }}</p>
                  <small>{{ item.basis }}</small>
                </div>
              </article>
            </div>
          </div>
          <div class="result-block paywall-block">
            <h3>第十集付费卡点候选</h3>
            <div class="paywall-list content-card-grid">
              <article
                v-for="(item, index) in result?.episode_10_paywall_hooks || []"
                :key="index"
              >
                <header>
                  <strong>候选 {{ index + 1 }}</strong
                  ><span>{{ item.hook_type }}</span>
                </header>
                <p>{{ item.content }}</p>
                <small>{{ item.appeal }}</small>
              </article>
            </div>
          </div>
        </section>
        <section
          v-else
          class="result-stack"
        >
          <div class="result-block">
            <h3>补充分析</h3>
            <div class="content-card-grid custom-analysis-list">
              <article
                v-for="(item, index) in result?.custom_analysis || []"
                :key="`${item.objective}-${index}`"
              >
                <header>
                  <strong>{{ item.objective }}</strong>
                </header>
                <p>{{ item.conclusion }}</p>
                <small v-if="item.evidence?.length">原文依据：{{ item.evidence.join("；") }}</small>
              </article>
              <p
                v-if="!result?.custom_analysis?.length"
                class="empty-copy"
              >
                暂无补充分析
              </p>
            </div>
          </div>
          <div
            v-if="result?.unmatched_objectives?.length"
            class="result-block"
          >
            <h3>无法完成的目标</h3>
            <div class="content-card-grid custom-analysis-list">
              <article
                v-for="(item, index) in result.unmatched_objectives"
                :key="`${item.objective}-${index}`"
              >
                <header>
                  <strong>{{ item.objective }}</strong>
                </header>
                <p>{{ item.reason }}</p>
              </article>
            </div>
          </div>
        </section>
      </div>
    </template>

    <div
      v-else
      class="analysis-empty"
    >
      <LoaderCircle
        v-if="status === 'queued' || status === 'running'"
        class="analysis-loading-icon"
        :size="38"
      />
      <CircleX
        v-else-if="status === 'failed'"
        class="analysis-failed-icon"
        :size="38"
        stroke-width="1.3"
      />
      <BookOpenText
        v-else
        :size="38"
        stroke-width="1.3"
      />
      <strong>{{
        status === "queued" || status === "running" ? "正在分析剧本" : status === "failed" ? "分析失败" : "尚未开始分析"
      }}</strong>
      <p
        v-if="status === 'failed'"
        class="analysis-error-message"
      >
        {{ message || "剧本分析失败，请重试" }}
      </p>
    </div>
  </article>
</template>

<style scoped lang="scss">
.analysis-result {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--creative-surface);
  border: 1px solid var(--creative-line);
  border-radius: 12px;
  overflow: hidden;
}
.analysis-result__header {
  min-height: 48px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--creative-line);
}
.analysis-result__header strong {
  font-size: 14px;
}
.analysis-state {
  color: var(--web-success);
  font-size: 12px;
}
.analysis-state.is-running {
  color: var(--web-warning);
}
.analysis-state.is-failed {
  color: var(--web-danger);
}
.analysis-categories {
  padding: 10px;
  display: flex;
  gap: 8px;
  background: var(--creative-surface);
  border-bottom: 1px solid var(--creative-line);
}
.analysis-categories button {
  min-width: 0;
  min-height: 44px;
  padding: 8px 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 0;
  gap: 4px;
  color: var(--creative-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  cursor: pointer;
  font-size: 13px;
  transition:
    color 0.18s,
    background-color 0.18s,
    border-color 0.18s;
}
.analysis-categories button:hover {
  color: var(--creative-text);
  background: var(--creative-surface-raised);
}
.analysis-categories button.active {
  color: var(--creative-text);
  background: var(--web-hover);
  border-color: var(--creative-accent);
}
.analysis-categories button.active svg {
  color: var(--creative-accent-hover);
}
.analysis-categories button:focus {
  outline-color: var(--creative-accent);
}
.analysis-categories button span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.analysis-content {
  min-height: 0;
  padding: 18px;
  flex: 1;
  background: color-mix(in srgb, var(--creative-surface-raised) 46%, var(--creative-surface));
  overflow: auto;
}
.result-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.tag-section-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  align-items: stretch;
}
.tag-section-grid .result-block {
  min-height: 150px;
}
.result-block,
.summary-card,
.opening-grid article,
.highlight-list article,
.emotion-list article,
.episode-list article,
.character-list article,
.hook-list > article,
.paywall-list article,
.outline-list li {
  min-width: 0;
  background: var(--creative-surface);
  border: 1px solid var(--creative-line);
  border-radius: 10px;
  box-shadow: none;
}
.result-block,
.summary-card,
.opening-grid article {
  padding: 16px;
}
.result-block h3,
.summary-card > span,
.opening-grid article > span,
.highlight-list article > span {
  display: block;
  margin: 0 0 14px;
  padding-left: 11px;
  position: relative;
  color: var(--creative-text);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
}
.result-block h3::before,
.summary-card > span::before,
.opening-grid article > span::before,
.highlight-list article > span::before {
  width: 3px;
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 0;
  content: "";
  background: var(--creative-accent);
  border-radius: 3px;
}
.result-block p,
.summary-card p,
.opening-grid p {
  margin: 0;
  color: var(--creative-text);
  line-height: 1.75;
  white-space: pre-wrap;
}
.tag-list {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 9px;
}
.tag-list span {
  padding: 6px 11px;
  color: var(--creative-text);
  background: var(--creative-surface);
  border: 1px solid var(--creative-line);
  border-radius: 999px;
  font-size: 12px;
}
.summary-card p {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.8;
}
.highlight-list,
.emotion-list,
.episode-list,
.character-list,
.hook-list,
.paywall-list,
.custom-analysis-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.content-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  align-items: stretch;
}
.highlight-list article,
.emotion-list article,
.episode-list article,
.character-list article,
.paywall-list article {
  padding: 16px;
}
.custom-analysis-list article {
  padding: 16px;
  background: var(--creative-surface);
  border: 1px solid var(--creative-line);
  border-radius: 10px;
}
.custom-analysis-list p {
  margin: 7px 0 0;
  line-height: 1.65;
}
.custom-analysis-list small {
  display: block;
  margin-top: 7px;
  color: var(--creative-muted);
  line-height: 1.55;
}
article header span {
  color: var(--creative-accent-hover);
  font-size: 12px;
}
.highlight-list p,
.emotion-list p,
.episode-list p,
.character-list p,
.paywall-list p {
  margin: 7px 0 0;
  line-height: 1.65;
}
article header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.outline-list {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: story-outline;
  display: flex;
  flex-direction: column;
  gap: 10px;
  line-height: 1.65;
}
.outline-list li {
  min-height: 38px;
  padding: 8px 10px 8px 42px;
  position: relative;
  counter-increment: story-outline;
}
.outline-list li::before {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  position: absolute;
  top: 7px;
  left: 9px;
  content: counter(story-outline);
  color: var(--creative-accent-hover);
  background: var(--web-hover);
  border-radius: 7px;
  font-size: 12px;
  font-weight: 600;
}
.episode-list small,
.hook-list small,
.paywall-list small {
  display: block;
  margin-top: 7px;
  color: var(--creative-muted);
  line-height: 1.55;
}
.character-list dl {
  margin: 10px 0 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 10px;
  font-size: 12px;
}
.character-list dt {
  color: var(--creative-muted);
}
.character-list dd {
  margin: 0;
  line-height: 1.55;
}
.character-list article > header strong {
  font-size: 15px;
}
.character-list article > header span,
.episode-list article > header span,
.emotion-list article > header span,
.paywall-list article > header span {
  padding: 3px 7px;
  background: var(--web-hover);
  border-radius: 5px;
}
.opening-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.opening-grid article {
  min-height: 128px;
}
.opening-grid article p {
  font-size: 15px;
}
.hook-list > article {
  padding: 16px;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 11px;
}
.hook-number {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  color: var(--creative-text);
  background: var(--web-hover);
  border-radius: 7px;
  font-size: 13px;
}
.hook-list p {
  margin: 7px 0 0;
  line-height: 1.65;
}
.analysis-empty {
  min-height: 300px;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  flex-direction: column;
  gap: 10px;
  color: var(--creative-muted);
  text-align: center;
}
.analysis-loading-icon {
  color: var(--creative-accent);
  animation: analysis-loading-spin 0.9s linear infinite;
}
.analysis-failed-icon {
  color: var(--web-danger);
}
@keyframes analysis-loading-spin {
  to {
    transform: rotate(360deg);
  }
}
.analysis-empty strong {
  color: var(--creative-text);
  font-size: 15px;
}
.analysis-empty p,
.empty-copy {
  margin: 0;
  color: var(--creative-muted);
  font-size: 12px;
  line-height: 1.6;
}
.analysis-empty .analysis-error-message {
  width: min(100%, 720px);
  color: var(--web-danger);
  line-height: 1.7;
  text-align: left;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
@media (max-width: 640px) {
  .analysis-categories {
    padding: 8px 4px;
    gap: 2px;
  }
  .analysis-categories button {
    padding: 8px 2px;
    font-size: 12px;
  }
  .analysis-categories button svg {
    display: none;
  }
  .opening-grid {
    grid-template-columns: 1fr;
  }
  .analysis-content {
    padding: 12px;
  }
  .tag-section-grid,
  .content-card-grid {
    grid-template-columns: 1fr;
  }
  .result-block,
  .summary-card,
  .opening-grid article {
    padding: 14px;
  }
}
</style>
