<script setup>
import { onBeforeUnmount } from 'vue'

const props = defineProps({
  dateMain: {
    type: String,
    required: true,
  },
  dateWeekday: {
    type: String,
    required: true,
  },
  dateWeekdayTone: {
    type: String,
    default: 'text-ink',
  },
  dday: {
    type: String,
    default: '',
  },
  showDday: {
    type: Boolean,
    default: true,
  },
  comment: {
    type: String,
    required: true,
  },
  totalTime: {
    type: String,
    required: true,
  },
  tasks: {
    type: Array,
    required: true,
  },
  memo: {
    type: Array,
    required: true,
  },
  hours: {
    type: Array,
    required: true,
  },
  timetable: {
    type: Array,
    required: true,
  },
  brand: {
    type: String,
    default: 'SORI.STUDIO',
  },
})

const emit = defineEmits([
  'update:comment',
  'update:task-label',
  'update:task-title',
  'toggle:task',
  'update:memo-label',
  'update:memo',
  'update:timetable',
])

let dragState = null

function shouldShowTaskPlaceholder(index) {
  return index === 0 && props.tasks.every((task) => !task.title.trim())
}

function buildTimedRange(baseTimetable, startIndex, endIndex, nextValue) {
  const nextTimetable = [...baseTimetable]
  const rangeStart = Math.min(startIndex, endIndex)
  const rangeEnd = Math.max(startIndex, endIndex)

  for (let index = rangeStart; index <= rangeEnd; index += 1) {
    nextTimetable[index] = nextValue
  }

  return nextTimetable
}

function startTimetableDrag(index, event) {
  if (event.button !== 0 && event.button !== 2) {
    return
  }

  const shouldFill = event.button === 2 ? false : !props.timetable[index]

  dragState = {
    startIndex: index,
    baseTimetable: [...props.timetable],
    nextValue: shouldFill,
  }

  emit('update:timetable', buildTimedRange(dragState.baseTimetable, index, index, dragState.nextValue))
}

function moveTimetableDrag(index) {
  if (!dragState) {
    return
  }

  emit(
    'update:timetable',
    buildTimedRange(dragState.baseTimetable, dragState.startIndex, index, dragState.nextValue),
  )
}

function stopTimetableDrag() {
  dragState = null
}

window.addEventListener('pointerup', stopTimetableDrag)
onBeforeUnmount(() => {
  window.removeEventListener('pointerup', stopTimetableDrag)
})
</script>

<template>
  <article
    class="planner-sheet flex w-full max-w-[762px] flex-col gap-3 bg-paper px-4 py-4 text-[10px] font-bold tracking-[0.16em] text-ink shadow-paper sm:px-8 sm:py-8 lg:px-12 lg:py-12"
  >
    <div class="planner-sheet__meta flex flex-col gap-4 py-3 sm:py-[18px]">
      <div class="planner-sheet__meta-top flex flex-col gap-3 sm:gap-4" :class="props.showDday ? 'sm:flex-row' : ''">
        <div class="relative min-h-[82px] border-t border-ink px-[10px] pt-[10px]" :class="props.showDday ? 'w-full sm:w-[394px] sm:flex-1' : 'w-full flex-1'">
          <span class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">YEAR / MONTH / DAY</span>
          <p class="pt-5 text-[11px] tracking-[0.2em] text-ink sm:pt-6 sm:text-sm">
            <span>{{ dateMain }}</span>
            <span class="ml-1" :class="dateWeekdayTone">{{ dateWeekday }}</span>
          </p>
        </div>
        <div v-if="props.showDday" class="relative min-h-[82px] w-full border-t border-ink px-[10px] pt-[10px] sm:w-[210px]">
          <span class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">D-DAY</span>
          <p
            class="pt-5 text-[11px] tracking-[0.14em] text-ink sm:pt-6 sm:text-sm"
            style="
              display: -webkit-box;
              -webkit-line-clamp: 3;
              -webkit-box-orient: vertical;
              overflow: hidden;
              text-overflow: ellipsis;
              word-break: break-word;
            "
          >
            {{ dday }}
          </p>
        </div>
      </div>
      <div class="planner-sheet__meta-bottom flex flex-col gap-3 border-b border-ink pb-3 sm:gap-4 sm:pb-[18px] lg:flex-row">
        <div class="relative min-h-[82px] w-full flex-1 border-t border-ink px-[10px] pt-[10px] lg:w-[394px]">
          <span class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">COMMENT</span>
          <textarea
            :value="comment"
            rows="3"
            class="mt-3 h-[54px] w-full resize-none bg-transparent pt-2 text-[11px] font-semibold normal-case tracking-[0.06em] text-stone-700 outline-none placeholder:text-stone-400 sm:mt-4 sm:text-xs"
            placeholder="오늘의 코멘트를 적어 주세요."
            @input="emit('update:comment', $event.target.value)"
          />
        </div>
        <div class="relative min-h-[82px] w-full border-t border-ink px-[10px] pt-[10px] lg:w-[210px]">
          <span class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">총 시간</span>
          <p class="pt-5 text-[11px] tracking-[0.2em] text-ink sm:pt-6 sm:text-sm">{{ totalTime }}</p>
        </div>
      </div>
    </div>

    <div class="planner-sheet__body flex flex-col gap-5 py-[10px] lg:flex-row lg:gap-4">
      <div class="planner-sheet__lists flex w-full flex-1 flex-col gap-7 sm:gap-9 lg:w-[394px]">
        <section class="relative">
          <div class="absolute -top-[9px] left-0 bg-paper px-[2px] text-muted">TASKS</div>
          <div class="border-t border-ink">
            <div
              v-for="(task, index) in tasks"
              :key="task.id"
              class="flex min-h-[38px] items-center border-b"
              :class="index % 5 === 4 || index === tasks.length - 1 ? 'border-ink' : 'border-line'"
            >
              <div class="h-full w-[52px] shrink-0 border-r border-dashed border-ink px-1.5 py-[7px] sm:w-[62px] sm:px-2">
                <input
                  :value="task.label"
                  type="text"
                  class="w-full bg-transparent text-center text-[9px] font-semibold tracking-[0.08em] text-stone-500 outline-none placeholder:text-stone-300"
                  @input="emit('update:task-label', { index, value: $event.target.value })"
                />
              </div>
              <div class="flex min-w-0 flex-1 items-center px-2 sm:px-3">
                <input
                  :value="task.title"
                  type="text"
                  class="w-full truncate bg-transparent text-[10px] font-semibold normal-case tracking-[0.04em] text-stone-800 outline-none placeholder:text-stone-400 sm:text-[11px] sm:tracking-[0.06em]"
                  :placeholder="shouldShowTaskPlaceholder(index) ? '할 일을 입력해 주세요.' : ''"
                  @input="emit('update:task-title', { index, value: $event.target.value })"
                />
              </div>
              <div class="flex h-full w-[36px] shrink-0 items-center justify-center p-[8px] sm:w-[42px] sm:p-[10px]">
                <button
                  type="button"
                  class="flex h-full w-full items-center justify-center border border-dashed transition"
                  :class="task.checked ? 'border-ink bg-stone-100 text-ink' : 'border-ink/60 text-transparent'"
                  @click="emit('toggle:task', index)"
                >
                  <span class="text-sm leading-none">✓</span>
                </button>
              </div>
            </div>
          </div>
        </section>

        <section class="relative">
          <div class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">MEMO</div>
          <div class="border-t border-ink">
            <div
              v-for="(memoItem, index) in memo"
              :key="`memo-${index}`"
              class="flex min-h-[38px] items-center border-b"
              :class="index === memo.length - 1 ? 'border-ink' : 'border-line'"
            >
              <div class="h-full w-[52px] shrink-0 border-r border-dashed border-ink px-1.5 py-[7px] sm:w-[62px] sm:px-2">
                <input
                  :value="memoItem.label"
                  type="text"
                  class="w-full bg-transparent text-center text-[9px] font-semibold tracking-[0.08em] text-stone-500 outline-none placeholder:text-stone-300"
                  @input="emit('update:memo-label', { index, value: $event.target.value })"
                />
              </div>
              <div class="flex flex-1 items-center px-2 sm:px-3">
                <input
                  :value="memoItem.text"
                  type="text"
                  class="w-full bg-transparent text-[10px] font-semibold normal-case tracking-[0.04em] text-stone-700 outline-none placeholder:text-stone-400 sm:text-[11px] sm:tracking-[0.06em]"
                  @input="emit('update:memo', { index, value: $event.target.value })"
                />
              </div>
            </div>
          </div>
        </section>
      </div>

      <section class="planner-sheet__timetable relative w-full shrink-0 lg:w-[210px]">
        <div class="absolute -top-2 left-0 bg-paper px-[2px] text-muted">TIME TABLE</div>
        <div class="planner-sheet__timetable-scroll overflow-x-auto pb-1">
          <div class="planner-sheet__timetable-grid min-w-[210px] border-t border-ink">
            <div
              v-for="(hour, index) in hours"
              :key="`${hour}-${index}`"
              class="flex h-[26px] border-b sm:h-[30px]"
              :class="index === hours.length - 1 ? 'border-ink' : 'border-line'"
            >
              <div
                class="flex h-full w-[30px] touch-none select-none items-center justify-center border-r border-ink text-[9px] text-ink"
                @pointerdown.prevent
              >
                {{ hour }}
              </div>
              <div
                v-for="quarter in 6"
                :key="quarter"
                :class="props.timetable[index * 6 + quarter - 1] ? 'bg-stone-800/90' : 'bg-transparent'"
                class="h-full w-[30px] cursor-crosshair border-r border-dashed border-line transition-colors last:border-r-0 touch-none select-none"
                @contextmenu.prevent
                @pointerdown.prevent="startTimetableDrag(index * 6 + quarter - 1, $event)"
                @pointerenter="moveTimetableDrag(index * 6 + quarter - 1)"
              />
            </div>
          </div>
        </div>
      </section>
    </div>

    <div class="flex justify-end">
      <p class="text-[10px] tracking-[0.18em] text-ink">{{ brand }}</p>
    </div>
  </article>
</template>
