<script setup lang="ts">
type UploadType = "slides" | "past_paper" | "lab_worksheet";

interface UploadedFile {
  file: File
  uploadId: string | null
  detectedType: UploadType | null
  overrideType: UploadType | null
  uploading: boolean
  error: string | null
}

const router = useRouter();

const uploadedFiles = ref<UploadedFile[]>([]);
const editingIndex = ref<number | null>(null);

const dragging = ref(false);
const submitting = ref(false);
const submitted = ref(false);
const formError = ref<string | null>(null);

const typeLabels: Record<UploadType, string> = {
  slides: "Lecture Slides",
  past_paper: "Past Paper",
  lab_worksheet: "Lab Worksheet",
};

function effectiveType(f: UploadedFile): UploadType | null {
  return f.overrideType ?? f.detectedType;
}

function onDrop(e: DragEvent) {
  dragging.value = false;
  addFiles(Array.from(e.dataTransfer?.files ?? []));
}

function onFileInput(e: Event) {
  const input = e.target as HTMLInputElement;
  addFiles(Array.from(input.files ?? []));
  input.value = "";
}

function addFiles(newFiles: File[]) {
  for (const f of newFiles) {
    if (f.type !== "application/pdf") continue;
    uploadedFiles.value.push({
      file: f,
      uploadId: null,
      detectedType: null,
      overrideType: null,
      uploading: false,
      error: null,
    });
  }
}

function removeFile(i: number) {
  uploadedFiles.value.splice(i, 1);
  if (editingIndex.value === i) editingIndex.value = null;
}

async function uploadFile(entry: UploadedFile, courseId: string) {
  entry.uploading = true;
  entry.error = null;
  try {
    const fd = new FormData();
    fd.append("file", entry.file);
    const res = await $fetch<{ uploadId: string; type: UploadType }>(
      `/api/courses/${courseId}/upload`,
      { method: "POST", body: fd }
    );
    entry.uploadId = res.uploadId;
    entry.detectedType = res.type;
  } catch (err: any) {
    entry.error = err?.data?.message ?? "Upload failed";
  } finally {
    entry.uploading = false;
  }
}

async function applyOverride(entry: UploadedFile, newType: UploadType) {
  if (!entry.uploadId) return;
  entry.overrideType = newType;
  editingIndex.value = null;
  try {
    await $fetch(`/api/uploads/${entry.uploadId}`, {
      method: "PATCH",
      body: { type: newType },
    });
  } catch {
    entry.overrideType = null;
  }
}

async function submit() {
  if (uploadedFiles.value.length === 0) {
    formError.value = "Add at least one PDF to continue.";
    return;
  }
  formError.value = null;
  submitting.value = true;
  try {
    const { courseId } = await $fetch<{ courseId: string }>("/api/courses", {
      method: "POST",
    });
    for (const entry of uploadedFiles.value) {
      await uploadFile(entry, courseId);
    }
    if (uploadedFiles.value.some((f) => f.error)) {
      submitting.value = false;
      return;
    }
    await $fetch(`/api/courses/${courseId}/generate`, { method: "POST" });
    submitted.value = true;
    setTimeout(() => router.push("/"), 3000);
  } catch (err: any) {
    formError.value = err?.data?.message ?? "Something went wrong. Please try again.";
    submitting.value = false;
  }
}
</script>

<template>
  <div class="upload-page">
    <div class="upload-inner">

      <!-- back -->
      <NuxtLink to="/" class="back-link">
        <svg width="14" height="14" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
          <path d="M12.5 5l-5 5 5 5"/>
        </svg>
        Back
      </NuxtLink>

      <!-- heading -->
      <div class="upload-head">
        <h1 class="upload-title">Create a new course</h1>
        <p class="upload-sub">Upload your materials and we'll build a complete learning path.</p>
      </div>

      <!-- drop zone -->
      <div
        class="drop-zone"
        :class="{ 'drop-zone--active': dragging }"
        @dragover.prevent="dragging = true"
        @dragleave.prevent="dragging = false"
        @drop.prevent="onDrop"
        @click="($refs.fileInput as HTMLInputElement).click()"
      >
        <input ref="fileInput" type="file" accept=".pdf" multiple class="hidden" @change="onFileInput" />
        <div class="drop-inner">
          <div class="drop-icon-wrap">
            <svg width="28" height="28" fill="none" viewBox="0 0 24 24" stroke="var(--accent)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
              <path d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
            </svg>
          </div>
          <p class="drop-text">Drop PDFs here, or <span class="drop-browse">browse files</span></p>
          <p class="drop-hint">slides · past papers · lab worksheets</p>
        </div>
      </div>

      <!-- file list -->
      <TransitionGroup name="file-list" tag="div" class="file-list">
        <div
          v-for="(f, i) in uploadedFiles"
          :key="f.file.name + i"
          class="file-row"
        >
          <div class="file-row-left">
            <div class="file-pdf-label">PDF</div>
            <div class="file-info">
              <p class="file-name">{{ f.file.name }}</p>

              <div v-if="f.uploading" class="detecting-row">
                <div class="detecting-dots"><span /><span /><span /></div>
                <span class="detecting-text">detecting type…</span>
              </div>

              <p v-else-if="f.error" class="file-error">{{ f.error }}</p>

              <div v-else-if="effectiveType(f)" class="type-row">
                <span class="type-badge" :class="`type-badge--${effectiveType(f)}`">
                  {{ typeLabels[effectiveType(f)!] }}
                  <span v-if="f.overrideType" class="opacity-50"> · edited</span>
                </span>
                <button v-if="f.uploadId" class="change-btn" @click.stop="editingIndex = editingIndex === i ? null : i">
                  {{ editingIndex === i ? 'cancel' : 'change' }}
                </button>
              </div>

              <div v-if="editingIndex === i && f.uploadId" class="type-select-wrap">
                <select
                  class="type-select"
                  :value="effectiveType(f) ?? ''"
                  @change="applyOverride(f, ($event.target as HTMLSelectElement).value as UploadType)"
                  @click.stop
                >
                  <option value="slides">Lecture Slides</option>
                  <option value="past_paper">Past Paper</option>
                  <option value="lab_worksheet">Lab Worksheet</option>
                </select>
              </div>
            </div>
          </div>

          <button class="remove-btn" @click.stop="removeFile(i)">
            <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
            </svg>
          </button>
        </div>
      </TransitionGroup>

      <!-- submitted -->
      <div v-if="submitted" class="submitted-msg">
        <svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="var(--green)" stroke-width="2.5">
          <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
        </svg>
        <span>Your course is being generated — check back in a few minutes</span>
      </div>

      <p v-else-if="formError" class="form-error">{{ formError }}</p>

      <button
        v-if="!submitted"
        class="submit-btn"
        :class="{ 'submit-btn--loading': submitting }"
        :disabled="submitting || uploadedFiles.length === 0"
        @click="submit"
      >
        <span v-if="!submitting">Generate my course →</span>
        <span v-else class="btn-loading">
          <span class="btn-dots"><span /><span /><span /></span>
          Uploading your materials
        </span>
      </button>

    </div>
  </div>
</template>

<style scoped>
.upload-page {
  padding: 40px 48px;
  min-height: 100vh;
}

.upload-inner {
  max-width: 560px;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-3);
  text-decoration: none;
  margin-bottom: 32px;
  transition: color 0.15s;
}
.back-link:hover { color: var(--text); }

.upload-head {
  margin-bottom: 32px;
}

.upload-title {
  font-family: "Lora", serif;
  font-size: 26px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.4px;
  margin-bottom: 6px;
}

.upload-sub {
  font-size: 14px;
  color: var(--text-2);
  line-height: 1.6;
}

.drop-zone {
  background: var(--surface);
  border: 2px dashed var(--border-2);
  border-radius: var(--r-surface);
  padding: 48px 24px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
  margin-bottom: 16px;
}
.drop-zone:hover { border-color: var(--accent); }
.drop-zone--active {
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-light);
}

.drop-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}

.drop-icon-wrap {
  margin-bottom: 4px;
}

.drop-text {
  font-size: 14px;
  color: var(--text-2);
  font-weight: 500;
}

.drop-browse {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.drop-hint {
  font-size: 12px;
  color: var(--text-3);
  letter-spacing: 0.04em;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

.file-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
}

.file-row-left {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.file-pdf-label {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-3);
  margin-top: 2px;
  flex-shrink: 0;
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-size: 14px;
  color: var(--text);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.detecting-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.detecting-text {
  font-size: 12px;
  color: var(--text-3);
}

.file-error {
  font-size: 12px;
  color: oklch(42% 0.12 15);
  margin-top: 4px;
}

.type-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}

.type-badge {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 20px;
  display: inline-block;
  font-weight: 500;
}

.type-badge--slides {
  background: var(--accent-light);
  color: var(--accent);
  border: 1px solid var(--accent-dim);
}

.type-badge--past_paper {
  background: oklch(95% 0.03 80);
  color: oklch(40% 0.12 65);
  border: 1px solid oklch(85% 0.05 75);
}

.type-badge--lab_worksheet {
  background: var(--green-light);
  color: var(--green);
  border: 1px solid oklch(85% 0.05 155);
}

.change-btn {
  font-size: 11px;
  color: var(--text-3);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.change-btn:hover { color: var(--accent); }

.type-select-wrap {
  margin-top: 8px;
}

.type-select {
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  color: var(--text);
  font-size: 13px;
  padding: 6px 10px;
  border-radius: var(--r-sm);
  outline: none;
}

.remove-btn {
  flex-shrink: 0;
  color: var(--text-3);
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px;
  margin-top: 2px;
  transition: color 0.15s;
}
.remove-btn:hover { color: var(--text); }

.submitted-msg {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--green);
  background: var(--green-light);
  border: 1px solid oklch(85% 0.05 155);
  border-radius: var(--r-btn);
  padding: 12px 16px;
  margin-bottom: 16px;
}

.form-error {
  font-size: 12px;
  color: oklch(42% 0.12 15);
  margin-bottom: 12px;
}

.submit-btn {
  width: 100%;
  background: var(--accent);
  color: white;
  font-size: 15px;
  font-weight: 500;
  height: 52px;
  border-radius: var(--r-btn);
  border: none;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.1s;
}
.submit-btn:hover:not(:disabled) { opacity: 0.88; }
.submit-btn:active:not(:disabled) { transform: scale(0.99); }
.submit-btn--loading,
.submit-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.detecting-dots, .btn-dots { display: flex; gap: 3px; align-items: center; }
.detecting-dots span, .btn-dots span {
  width: 4px; height: 4px; border-radius: 50%;
  animation: dot-pulse 1.4s ease-in-out infinite;
}

.detecting-dots span { background: var(--text-3); }
.btn-dots span { background: rgba(255,255,255,0.8); }

.detecting-dots span:nth-child(2), .btn-dots span:nth-child(2) { animation-delay: 0.2s; }
.detecting-dots span:nth-child(3), .btn-dots span:nth-child(3) { animation-delay: 0.4s; }

@keyframes dot-pulse {
  0%, 80%, 100% { opacity: 0.2; transform: scale(0.8); }
  40% { opacity: 1; transform: scale(1); }
}

.file-list-enter-active { transition: all 0.25s ease; }
.file-list-leave-active { transition: all 0.2s ease; }
.file-list-enter-from { opacity: 0; transform: translateY(-6px); }
.file-list-leave-to   { opacity: 0; transform: translateX(10px); }
</style>
