<script setup lang="ts">
import { request } from '~/utils/http/factory'

// ── Types ──

interface CardRef {
  id: number
  title: string
  type: string
  description?: string | null
  aspectRatio?: number | null
  coverUrl: string | null
  sortOrder: number
}

export interface ArticleData {
  id?: number
  title: string
  content: string
  summary?: string | null
  cover?: string | null
  status: 'draft' | 'published'
  createdAt?: Date
  updatedAt?: Date
  cards: CardRef[]
}

// ── Props / Emits ──

const props = defineProps<{
  visible: boolean
  mode: 'create' | 'edit'
  article: ArticleData | null
}>()

const emit = defineEmits<{
  'update:visible': [value: boolean]
  'saved': []
}>()

const { $toast } = useNuxtApp()

// ── Local state ──

const saving = ref(false)

const form = reactive({
  title: '',
  content: '',
  summary: '',
  cover: '',
  status: 'draft' as 'draft' | 'published',
  cardIds: [] as { cardId: number; sortOrder?: number }[],
})

// ── Watch for edit data ──

watch(
  () => props.visible,
  (vis) => {
    if (!vis) return
    if (props.mode === 'edit' && props.article) {
      form.title = props.article.title
      form.content = props.article.content
      form.summary = props.article.summary ?? ''
      form.cover = props.article.cover ?? ''
      form.status = props.article.status
      form.cardIds = props.article.cards.map((c) => ({
        cardId: c.id,
        sortOrder: c.sortOrder,
      }))
    } else {
      form.title = ''
      form.content = ''
      form.summary = ''
      form.cover = ''
      form.status = 'draft'
      form.cardIds = []
    }
  },
)

// ── Char counts ──

const titleCount = computed(() => form.title.length)
const summaryCount = computed(() => form.summary.length)

// ── Actions ──

function close() {
  emit('update:visible', false)
}

async function handleSave() {
  if (!form.title.trim()) {
    $toast.warning('请输入标题')
    return
  }
  if (!form.content.trim()) {
    $toast.warning('请输入内容')
    return
  }

  saving.value = true
  try {
    const body: Record<string, unknown> = {
      title: form.title.trim(),
      content: form.content,
      summary: form.summary.trim() || null,
      cover: form.cover.trim() || null,
      status: form.status,
      cardIds: form.cardIds.length > 0 ? form.cardIds : null,
    }

    if (props.mode === 'create') {
      await request('/api/articles', { method: 'POST', body })
      $toast.success('文章已创建')
    } else {
      await request(`/api/articles/${props.article!.id}`, {
        method: 'PUT',
        body,
      })
      $toast.success('文章已更新')
    }
    emit('update:visible', false)
    emit('saved')
  } catch (e: any) {
    $toast.error(e?.data?.message || e?.message || '保存失败')
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <BoDialog :show="visible" style="width: 80vw;max-width:1200px;" @update:show="(v: boolean) => emit('update:visible', v)">
    <div class="afd">
      <!-- Header -->
      <div class="afd-header">
        <div class="afd-header-icon">
          <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
            <path
              d="M4 3h9l4 4v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"
              stroke="currentColor"
              stroke-width="1.5"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
            <path
              d="M13 3v4h4M7 11h6M7 14h4"
              stroke="currentColor"
              stroke-width="1.5"
              stroke-linecap="round"
            />
          </svg>
        </div>
        <div class="afd-header-text">
          <h3 class="afd-title">{{ mode === 'create' ? '新建文章' : '编辑文章' }}</h3>
          <p class="afd-subtitle">
            {{ mode === 'create' ? '撰写一篇新文章并关联卡片' : '修改文章内容与关联' }}
          </p>
        </div>
      </div>

      <!-- Body -->
      <div class="afd-body">
        <div class="afd-grid">
          <!-- Left Column -->
          <div class="afd-col">
            <!-- Section: Basic Info -->
            <div class="afd-section">
              <span class="afd-section-label">基本信息</span>

              <!-- Title -->
              <div class="afd-field">
                <div class="afd-field-head">
                  <label class="afd-label">标题</label>
                  <span
                    class="afd-counter"
                    :class="{ over: titleCount > 255 }"
                  >{{ titleCount }}/255</span>
                </div>
                <input
                  v-model="form.title"
                  type="text"
                  class="afd-input"
                  placeholder="输入文章标题"
                  maxlength="255"
                />
              </div>

              <!-- Summary -->
              <div class="afd-field">
                <div class="afd-field-head">
                  <label class="afd-label">摘要</label>
                  <span
                    class="afd-counter"
                    :class="{ over: summaryCount > 500 }"
                  >{{ summaryCount }}/500</span>
                </div>
                <textarea
                  v-model="form.summary"
                  class="afd-textarea"
                  placeholder="简短描述（可选），用于列表预览"
                  rows="3"
                  maxlength="500"
                />
              </div>

              <!-- Cover -->
              <div class="afd-field">
                <label class="afd-label">封面图片</label>
                <input
                  v-model="form.cover"
                  type="url"
                  class="afd-input"
                  placeholder="https://… 封面图片链接（可选）"
                />
              </div>
            </div>

            <!-- Section: Status -->
            <div class="afd-section">
              <span class="afd-section-label">发布状态</span>
              <div class="afd-segmented">
                <button
                  class="afd-segmented-btn"
                  :class="{ active: form.status === 'draft' }"
                  @click="form.status = 'draft'"
                >
                  <svg
                    width="14"
                    height="14"
                    viewBox="0 0 14 14"
                    fill="none"
                    class="afd-segmented-icon"
                  >
                    <path
                      d="M11 2H3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z"
                      stroke="currentColor"
                      stroke-width="1.3"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                    />
                    <path
                      d="M5 7h4M5 9.5h2.5"
                      stroke="currentColor"
                      stroke-width="1.3"
                      stroke-linecap="round"
                    />
                  </svg>
                  草稿
                </button>
                <button
                  class="afd-segmented-btn"
                  :class="{ active: form.status === 'published' }"
                  @click="form.status = 'published'"
                >
                  <svg
                    width="14"
                    height="14"
                    viewBox="0 0 14 14"
                    fill="none"
                    class="afd-segmented-icon"
                  >
                    <path
                      d="M12 3.5 5.5 10 2 6.5"
                      stroke="currentColor"
                      stroke-width="1.5"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                    />
                  </svg>
                  发布
                </button>
              </div>
            </div>
          </div>

          <!-- Right Column -->
          <div class="afd-col">
            <!-- Section: Content -->
            <div class="afd-section afd-section-content">
              <span class="afd-section-label">正文</span>
              <div class="afd-editor-shell">
                <div class="afd-editor-toolbar">
                  <span class="afd-editor-format">Markdown</span>
                </div>
                <ClientOnly>
                  <BoMdEditor
                    v-model="form.content"
                    placeholder="撰写文章内容…"
                    height="100%"
                    min-height="320px"
                  />
                  <template #fallback>
                    <textarea
                      v-model="form.content"
                      class="afd-editor-fallback"
                      placeholder="撰写文章内容…"
                      rows="18"
                    />
                  </template>
                </ClientOnly>
              </div>
            </div>

            <!-- Section: Cards -->
            <div class="afd-section">
              <span class="afd-section-label">关联卡片</span>
              <CardPicker v-model="form.cardIds" />
            </div>
          </div>
        </div>
      </div>

      <!-- Footer -->
      <div class="afd-footer">
        <button class="afd-btn-cancel" @click="close">取消</button>
        <button
          class="afd-btn-save"
          :disabled="saving"
          @click="handleSave"
        >
          <svg
            v-if="saving"
            class="afd-btn-spinner"
            width="14"
            height="14"
            viewBox="0 0 14 14"
            fill="none"
          >
            <circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-opacity="0.3" stroke-width="1.5" />
            <path d="M7 1.5A5.5 5.5 0 0 1 12.5 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
          </svg>
          {{ saving ? '保存中…' : '保存' }}
        </button>
      </div>
    </div>
  </BoDialog>
</template>

<style scoped>
/* ── Root ── */

.afd {
  background: #fff;
  border-radius: 14px;
  width: 80vw;
  max-width: 1200px;
  display: flex;
  flex-direction: column;
}

/* ── Header ── */

.afd-header {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 24px 28px 0;
}

.afd-header-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: #efe9de;
  color: #8b7e6a;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 2px;
}

.afd-header-text {
  flex: 1;
  min-width: 0;
}

.afd-title {
  font-size: 18px;
  font-weight: 600;
  color: #141413;
  margin: 0 0 2px;
  line-height: 1.3;
}

.afd-subtitle {
  font-size: 13px;
  color: #8e8b82;
  margin: 0;
  line-height: 1.4;
}

/* ── Body ── */

.afd-body {
  padding: 20px 28px;
}

/* ── Two-column grid ── */

.afd-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  align-items: start;
}

.afd-col {
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}

/* Right column: make content section fill remaining height */
.afd-section-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.afd-section-content .afd-editor-shell {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 360px;
}

/* ── Sections ── */

.afd-section {
  /* spacing handled by parent .afd-col gap */
}

.afd-section-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: #8e8b82;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  margin-bottom: 12px;
}

/* ── Fields ── */

.afd-field {
  margin-bottom: 16px;
}

.afd-field:last-child {
  margin-bottom: 0;
}

.afd-field-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.afd-label {
  font-size: 13px;
  font-weight: 500;
  color: #6c6a64;
}

.afd-counter {
  font-size: 11px;
  color: #b8b2a6;
  font-variant-numeric: tabular-nums;
}

.afd-counter.over {
  color: #c64545;
}

.afd-input {
  width: 100%;
  padding: 9px 14px;
  border: 1px solid #e6dfd8;
  border-radius: 8px;
  font-size: 14px;
  color: #3d3d3a;
  outline: none;
  background: #faf9f5;
  transition: border-color 0.2s;
  box-sizing: border-box;
  font-family: inherit;
}

.afd-input:focus {
  border-color: #cc785c;
  box-shadow: 0 0 0 3px rgba(204, 120, 92, 0.1);
}

.afd-input::placeholder {
  color: #b8b2a6;
}

.afd-textarea {
  width: 100%;
  padding: 9px 14px;
  border: 1px solid #e6dfd8;
  border-radius: 8px;
  font-size: 14px;
  color: #3d3d3a;
  outline: none;
  background: #faf9f5;
  resize: vertical;
  font-family: inherit;
  transition: border-color 0.2s;
  box-sizing: border-box;
  line-height: 1.55;
}

.afd-textarea:focus {
  border-color: #cc785c;
  box-shadow: 0 0 0 3px rgba(204, 120, 92, 0.1);
}

.afd-textarea::placeholder {
  color: #b8b2a6;
}

/* ── Editor Shell ── */

.afd-editor-shell {
  border: 1px solid #e6dfd8;
  border-radius: 10px;
  overflow: hidden;
  background: #faf9f5;
}

.afd-editor-toolbar {
  display: flex;
  align-items: center;
  padding: 8px 14px;
  background: #f5f0e8;
  border-bottom: 1px solid #e6dfd8;
}

.afd-editor-format {
  font-size: 11px;
  font-weight: 600;
  color: #8b7e6a;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: #e8e0d2;
  padding: 3px 10px;
  border-radius: 4px;
}

.afd-editor-fallback {
  width: 100%;
  border: none;
  border-radius: 0;
  padding: 14px;
  font-size: 14px;
  color: #3d3d3a;
  outline: none;
  background: #faf9f5;
  resize: vertical;
  font-family: inherit;
  box-sizing: border-box;
  line-height: 1.6;
}

.afd-editor-fallback::placeholder {
  color: #b8b2a6;
}

/* ── Segmented Control ── */

.afd-segmented {
  display: inline-flex;
  gap: 2px;
  background: #efe9de;
  border-radius: 10px;
  padding: 3px;
}

.afd-segmented-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 18px;
  border: none;
  background: none;
  font-size: 13px;
  font-weight: 500;
  color: #6c6a64;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}

.afd-segmented-btn.active {
  background: #fff;
  color: #141413;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}

.afd-segmented-btn:hover:not(.active) {
  color: #3d3d3a;
}

.afd-segmented-icon {
  flex-shrink: 0;
}

/* ── Footer ── */

.afd-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 28px 24px;
  border-top: 1px solid #efe9de;
}

.afd-btn-cancel {
  padding: 10px 22px;
  border: 1px solid #e6dfd8;
  border-radius: 8px;
  background: #fff;
  font-size: 14px;
  font-weight: 500;
  color: #6c6a64;
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
}

.afd-btn-cancel:hover {
  background: #f5f0e8;
  color: #3d3d3a;
}

.afd-btn-save {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 22px;
  border: none;
  border-radius: 8px;
  background: #cc785c;
  font-size: 14px;
  font-weight: 500;
  color: #fff;
  cursor: pointer;
  transition: background 0.15s;
  font-family: inherit;
}

.afd-btn-save:hover {
  background: #a9583e;
}

.afd-btn-save:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.afd-btn-spinner {
  animation: afd-spin 0.8s linear infinite;
}

@keyframes afd-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Responsive ── */

@media (max-width: 799px) {
  .afd {
    width: 100%;
    max-width: 100%;
    border-radius: 0;
  }

  .afd-header {
    padding: 20px 20px 0;
    gap: 12px;
  }

  .afd-body {
    padding: 16px 20px;
  }

  .afd-footer {
    padding: 14px 20px 20px;
  }

  .afd-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .afd-col {
    gap: 20px;
  }

  .afd-section-content .afd-editor-shell {
    min-height: 300px;
  }

  .afd-segmented {
    width: 100%;
  }

  .afd-segmented-btn {
    flex: 1;
    justify-content: center;
  }
}
</style>
