<template>
  <v-container fluid class="pt-2 pb-6">
    <div class="fc-series__head">
      <span class="fc-series__name">{{ store.series?.name || 'Series' }}</span>
      <span class="fc-series__count">
        {{ store.chapters.length }} chapter(s) · {{ store.pageCount }} page(s)
      </span>
      <v-btn
        v-if="store.pageCount > 0"
        size="small" variant="tonal" color="accent"
        prepend-icon="mdi-book-open"
        class="fc-series__read"
        @click="$router.push({ name: 'series-read', params: { tagId: store.tagId } })"
      >Read</v-btn>
    </div>

    <div class="fc-series__body">
      <!-- Chapters column -->
      <div class="fc-series__chapters">
        <template v-for="(ch, ci) in store.chapters" :key="ch.id">
          <section
            class="fc-chapter"
            :class="{ 'fc-chapter--target': ch.id === store.targetChapterId }"
          >
            <header class="fc-chapter__head">
              <span class="fc-chapter__num">{{ ch.chapter_number }}</span>
              <v-text-field
                v-model="titleDraft[ch.id]"
                :placeholder="`Chapter ${ch.chapter_number}`"
                density="compact" variant="plain" hide-details
                class="fc-chapter__title"
                @keydown.enter="commitTitle(ch)"
                @blur="commitTitle(ch)"
              />
              <span v-if="ch.is_placeholder" class="fc-chapter__ph">placeholder</span>
              <span v-else class="fc-chapter__pc">{{ ch.pages.length }} pg</span>

              <div class="fc-chapter__stated">
                <input
                  class="fc-chapter__num-in" type="number" min="0"
                  :value="ch.stated_page_start ?? ''" placeholder="–"
                  title="Stated first page"
                  @change="onStated(ch, 'start', $event)"
                >
                <span>–</span>
                <input
                  class="fc-chapter__num-in" type="number" min="0"
                  :value="ch.stated_page_end ?? ''" placeholder="–"
                  title="Stated last page"
                  @change="onStated(ch, 'end', $event)"
                >
              </div>

              <div class="fc-chapter__actions">
                <v-btn
                  size="x-small" variant="text" icon="mdi-chevron-up"
                  title="Move chapter up" :disabled="ci === 0"
                  @click="store.moveChapter(ch.id, -1)"
                />
                <v-btn
                  size="x-small" variant="text" icon="mdi-chevron-down"
                  title="Move chapter down"
                  :disabled="ci === store.chapters.length - 1"
                  @click="store.moveChapter(ch.id, 1)"
                />
                <v-btn
                  size="x-small" variant="text" icon="mdi-arrow-collapse-up"
                  title="Merge into previous chapter" :disabled="ci === 0"
                  @click="store.mergeChapter(ch.id, store.chapters[ci - 1].id)"
                />
                <v-btn
                  size="x-small" variant="text" icon="mdi-target"
                  :color="ch.id === store.targetChapterId ? 'accent' : undefined"
                  title="Add picked images here"
                  @click="store.targetChapterId = ch.id"
                />
                <v-btn
                  size="x-small" variant="text" icon="mdi-delete-outline"
                  title="Delete chapter (removes its pages from the series)"
                  @click="store.deleteChapter(ch.id)"
                />
              </div>
            </header>

            <div v-if="ch.is_placeholder" class="fc-chapter__reserved">
              Reserved slot — a section you don't have yet.
            </div>
            <div v-else-if="ch.pages.length === 0" class="fc-chapter__empty">
              No pages — pick this chapter (◎) then add from the right.
            </div>
            <div v-else class="fc-chapter__pages">
              <div
                v-for="(p, pi) in ch.pages" :key="p.image_id"
                class="fc-page" draggable="true"
                @dragstart="drag = { chapterId: ch.id, idx: pi }"
                @dragover.prevent
                @drop="onPageDrop(ch, pi)"
              >
                <span class="fc-page__pn">{{ p.page_number }}</span>
                <img :src="p.thumbnail_url" alt="" loading="lazy" />
                <div class="fc-page__actions">
                  <v-btn size="x-small" variant="text" icon="mdi-image-frame"
                         title="Make cover" @click="store.setCover(p.image_id)" />
                  <v-btn size="x-small" variant="text" icon="mdi-close"
                         title="Remove" @click="store.remove(p.image_id)" />
                </div>
              </div>
            </div>
          </section>

          <div
            v-if="store.gapAfter(ch.id)"
            class="fc-gap"
          >
            <v-icon size="x-small">mdi-alert-outline</v-icon>
            Gap: pages {{ store.gapAfter(ch.id).start }}–{{ store.gapAfter(ch.id).end }} missing
          </div>
        </template>

        <div v-if="store.chapters.length === 0" class="fc-series__empty">
          No chapters yet — add one, then add images from the right.
        </div>

        <div class="fc-series__chapter-add">
          <v-btn size="small" variant="tonal" prepend-icon="mdi-plus"
                 @click="store.createChapter()">Add chapter</v-btn>
          <v-btn size="small" variant="text" prepend-icon="mdi-bookmark-outline"
                 @click="store.createChapter({ isPlaceholder: true })">
            Add placeholder
          </v-btn>
        </div>
      </div>

      <!-- Picker column -->
      <div class="fc-series__picker">
        <div class="fc-series__pickerhead">
          <span>{{ store.pickerSelection.length }} selected</span>
          <v-btn
            size="small" color="accent" variant="flat"
            :disabled="store.pickerSelection.length === 0"
            @click="store.addSelected()"
          >Add to {{ targetLabel }}</v-btn>
        </div>
        <div class="fc-series__pickergrid">
          <div
            v-for="img in store.picker" :key="img.id"
            class="fc-series__pick"
            :class="{ on: store.pickerSelection.includes(img.id) }"
            @click="store.togglePick(img.id)"
          >
            <img :src="img.thumbnail_url" alt="" loading="lazy" />
          </div>
        </div>
        <div ref="sentinel" class="fc-series__sentinel" />
      </div>
    </div>
  </v-container>
</template>

<script setup>
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { useSeriesManageStore, moveItem } from '../stores/seriesManage.js'
import { useInfiniteScroll } from '../composables/useInfiniteScroll.js'

const route = useRoute()
const store = useSeriesManageStore()
const sentinel = ref(null)
const drag = ref(null)            // { chapterId, idx }
const titleDraft = reactive({})   // chapterId -> draft string

// Keep local title drafts in sync with the loaded chapters. Edits commit on
// blur/Enter, which refreshes and resets the draft to the saved value.
watch(() => store.chapters, (chs) => {
  Object.keys(titleDraft).forEach(k => delete titleDraft[k])
  for (const c of chs) titleDraft[c.id] = c.title || ''
}, { immediate: true })

const targetLabel = computed(() => {
  const ch = store.chapters.find(c => c.id === store.targetChapterId)
  if (!ch) return 'chapter'
  return ch.title || `Chapter ${ch.chapter_number}`
})

function commitTitle(ch) {
  const v = (titleDraft[ch.id] || '').trim()
  if (v === (ch.title || '')) return
  store.renameChapter(ch.id, v || null)
}

function onStated(ch, which, ev) {
  const raw = ev.target.value
  const n = raw === '' ? null : parseInt(raw, 10)
  const start = which === 'start' ? n : ch.stated_page_start
  const end = which === 'end' ? n : ch.stated_page_end
  store.setChapterStated(ch.id, start, end)
}

function onPageDrop(chapter, toIdx) {
  if (!drag.value || drag.value.chapterId !== chapter.id) { drag.value = null; return }
  if (drag.value.idx === toIdx) { drag.value = null; return }
  const ordered = moveItem(
    chapter.pages.map(p => p.image_id), drag.value.idx, toIdx
  )
  drag.value = null
  store.reorderPages(chapter.id, ordered)
}

useInfiniteScroll(sentinel, () => store.loadPicker())

onMounted(async () => {
  await store.load(parseInt(route.params.tagId, 10))
  await store.loadPicker(true)
})
</script>

<style scoped>
.fc-series__head {
  display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px;
}
.fc-series__name { font-family: 'Fraunces', Georgia, serif; font-size: 22px; }
.fc-series__count {
  font-size: 13px; color: rgb(var(--v-theme-on-surface-variant));
}
.fc-series__body { display: flex; gap: 16px; align-items: flex-start; }
.fc-series__chapters {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px;
}

.fc-chapter {
  border: 1px solid rgb(var(--v-theme-surface-light));
  border-radius: 8px; padding: 8px 10px;
  background: rgb(var(--v-theme-surface));
}
.fc-chapter--target { border-color: rgb(var(--v-theme-accent), 0.7); }
.fc-chapter__head { display: flex; align-items: center; gap: 8px; }
.fc-chapter__num {
  flex: 0 0 auto; min-width: 22px; height: 22px; border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-variant-numeric: tabular-nums;
  background: rgb(var(--v-theme-accent), 0.16);
  color: rgb(var(--v-theme-accent));
}
.fc-chapter__title { flex: 1; min-width: 0; }
.fc-chapter__ph {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: rgb(var(--v-theme-on-surface-variant));
}
.fc-chapter__pc {
  font-size: 12px; color: rgb(var(--v-theme-on-surface-variant));
  font-variant-numeric: tabular-nums;
}
.fc-chapter__stated { display: inline-flex; align-items: center; gap: 4px; }
.fc-chapter__num-in {
  width: 42px; text-align: center; font-size: 12px;
  background: rgb(var(--v-theme-surface-light));
  border: 1px solid transparent; border-radius: 4px; padding: 2px 4px;
  color: rgb(var(--v-theme-on-surface));
}
.fc-chapter__num-in:focus { outline: none; border-color: rgb(var(--v-theme-accent)); }
.fc-chapter__actions { flex: 0 0 auto; display: inline-flex; }
.fc-chapter__reserved, .fc-chapter__empty {
  padding: 14px; text-align: center; font-size: 13px;
  color: rgb(var(--v-theme-on-surface-variant));
}
.fc-chapter__pages { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.fc-page {
  display: flex; align-items: center; gap: 10px; padding: 6px;
  background: rgb(var(--v-theme-surface-light)); border-radius: 6px; cursor: grab;
}
.fc-page img { width: 56px; height: 56px; object-fit: cover; border-radius: 4px; }
.fc-page__pn {
  width: 26px; text-align: center; font-variant-numeric: tabular-nums;
  color: rgb(var(--v-theme-on-surface-variant));
}
.fc-page__actions { margin-left: auto; }
.fc-gap {
  display: flex; align-items: center; gap: 6px; padding: 4px 10px;
  font-size: 12px; color: rgb(var(--v-theme-warning, var(--v-theme-accent)));
}
.fc-series__chapter-add { display: flex; gap: 8px; margin-top: 4px; }
.fc-series__empty {
  padding: 32px; text-align: center; color: rgb(var(--v-theme-on-surface-variant));
}

.fc-series__picker { flex: 1; min-width: 0; }
.fc-series__pickerhead {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.fc-series__pickergrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 6px;
}
.fc-series__pick {
  cursor: pointer; aspect-ratio: 1; overflow: hidden;
  border-radius: 4px; outline: 2px solid transparent;
}
.fc-series__pick img { width: 100%; height: 100%; object-fit: cover; }
.fc-series__pick.on { outline-color: rgb(var(--v-theme-accent)); }
.fc-series__sentinel { height: 40px; }

@media (max-width: 900px) {
  .fc-series__body { flex-direction: column; }
}
</style>
