<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { useAuth0 } from "@auth0/auth0-vue";
import { useRuntimeConfig } from "nuxt/app";

import DesignerCanvas from "~/components/designer/DesignerCanvas.vue";
import DesignerPreview from "~/components/designer/DesignerPreview.vue";
import DesignerToolbar from "~/components/designer/DesignerToolbar.vue";
import TemplatePicker from "~/components/designer/TemplatePicker.vue";

import { useDesignPersistence } from "../../composables/useDesignPersistence";
import { useSlipmatDesigner } from "~/composables/useSlipmatDesigner";

const runtimeConfig = useRuntimeConfig();
const auth0 = process.client ? useAuth0() : null;

const {
  templates,
  selectedTemplate,
  selectTemplate,
  displaySize,
  templateLabel,
  productionPixelSize,
  previewUrl,
  registerCanvas,
  unregisterCanvas,
  addTextbox,
  addShape,
  addImageFromFile,
  clearDesign,
  downloadPreview,
  downloadProduction,
  exportDesign,
  isExporting,
  activeFillColor,
  activeStrokeColor,
  canStyleSelection,
  setActiveFillColor,
  setActiveStrokeColor,
  zoomLevel,
  minZoom,
  maxZoom,
  setZoom,
  zoomIn,
  zoomOut,
  resetZoom,
} = useSlipmatDesigner();

const {
  designs,
  fetchDesigns,
  saveDesign,
  isSaving,
  isLoading: isLibraryLoading,
  lastError,
  isAuthenticated,
} = useDesignPersistence();

const projectName = ref("Untitled Slipmat");
const saveMessage = ref<string | null>(null);
const saveError = ref<string | null>(null);
const activeDesignId = ref<string | null>(null);

const userProfile = computed(() => auth0?.user.value ?? null);

const canSave = computed(
  () => isAuthenticated.value && !!previewUrl.value && !isExporting.value
);

const handleTemplateSelect = (templateId: string) => {
  selectTemplate(templateId);
};

const handleExport = async () => {
  await exportDesign();
};

const handleProjectNameUpdate = (value: string) => {
  projectName.value = value;
};

const formatTimestamp = (value: string | null) => {
  if (!value) {
    return "Never";
  }
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return "Unknown";
  }
  return new Intl.DateTimeFormat(undefined, {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date);
};

const handleSaveDesign = async () => {
  if (!canSave.value) {
    return;
  }
  saveError.value = null;

  try {
    const exported = await exportDesign();
    if (!exported) {
      return;
    }

    const saved = await saveDesign({
      id: activeDesignId.value ?? undefined,
      name:
        projectName.value.trim() ||
        `Slipmat ${new Intl.DateTimeFormat(undefined, {
          month: "short",
          day: "numeric",
          year: "numeric",
        }).format(new Date())}`,
      design: exported,
    });

    activeDesignId.value = saved.id;
    saveMessage.value = "Design saved to your library.";
    setTimeout(() => {
      saveMessage.value = null;
    }, 4000);
  } catch (error) {
    saveError.value = error instanceof Error ? error.message : String(error);
  }
};

const handleLogout = async () => {
  if (!auth0) {
    return;
  }

  await auth0.logout({
    logoutParams: {
      returnTo:
        runtimeConfig.public.auth0?.baseUrl ??
        (process.client ? window.location.origin : undefined),
    },
  });
};

if (process.client && auth0) {
  watch(
    () => auth0.isAuthenticated.value,
    async (authenticated) => {
      if (authenticated) {
        try {
          await fetchDesigns();
        } catch (error) {
          // Surface error through reactive ref
          saveError.value = error instanceof Error ? error.message : String(error);
        }
      } else {
        designs.value = [];
        activeDesignId.value = null;
      }
    },
    { immediate: true }
  );

  watch(lastError, (value) => {
    if (value) {
      saveError.value = value;
    }
  });
}

onMounted(async () => {
  if (auth0?.isAuthenticated.value) {
    try {
      await fetchDesigns();
    } catch (error) {
      saveError.value = error instanceof Error ? error.message : String(error);
    }
  }
});
</script>

<template>
  <main class="min-h-screen bg-slate-950 pb-16 text-slate-100">
    <div class="mx-auto max-w-6xl px-4 pt-12 sm:px-6 lg:px-8">
      <header class="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between">
        <div class="space-y-3">
          <p class="text-sm uppercase tracking-[0.35em] text-sky-400">
            Slipmatz Designer
          </p>
          <h1 class="text-3xl font-bold text-white sm:text-4xl">
            Craft custom slipmats ready for the pressing plant.
          </h1>
          <p class="max-w-3xl text-base text-slate-300">
            Pick a template, drop in artwork, and we’ll generate both a high-fidelity
            preview and a print-ready PNG at exact specs. Everything stays within a
            circular safe zone to ensure clean results on vinyl.
          </p>
        </div>
        <div
          v-if="userProfile"
          class="flex items-center gap-3 rounded-2xl border border-slate-800/70 bg-slate-900/70 px-4 py-3 shadow-lg shadow-slate-950/40"
        >
          <div class="text-right">
            <p class="text-[0.7rem] uppercase tracking-[0.3em] text-slate-500">
              Signed in
            </p>
            <p class="text-sm font-semibold text-white">
              {{ userProfile.name ?? userProfile.email ?? "Authenticated" }}
            </p>
          </div>
          <button
            type="button"
            class="rounded-lg border border-sky-500/60 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-sky-100 transition hover:bg-sky-500/10"
            @click="handleLogout"
          >
            Log out
          </button>
        </div>
      </header>

      <section class="mt-10 grid gap-8 lg:grid-cols-[320px_minmax(0,1fr)]">
        <div class="space-y-6">
          <TemplatePicker
            :templates="templates"
            :selected-template-id="selectedTemplate.id"
            @select="handleTemplateSelect"
          />

          <DesignerToolbar
            :on-add-text="addTextbox"
            :on-add-circle="() => addShape('circle')"
            :on-add-rectangle="() => addShape('rect')"
            :on-clear="clearDesign"
            :on-import-image="addImageFromFile"
            :on-fill-change="setActiveFillColor"
            :on-stroke-change="setActiveStrokeColor"
            :active-fill="activeFillColor"
            :active-stroke="activeStrokeColor"
            :can-style-selection="canStyleSelection"
            :zoom="zoomLevel"
            :min-zoom="minZoom"
            :max-zoom="maxZoom"
            :on-zoom-change="setZoom"
            :on-zoom-in="zoomIn"
            :on-zoom-out="zoomOut"
            :on-zoom-reset="resetZoom"
          />

          <DesignerPreview
            :preview-url="previewUrl"
            :template-label="templateLabel"
            :production-pixels="productionPixelSize"
            :is-exporting="isExporting"
            :project-name="projectName"
            :is-saving="isSaving"
            :can-save="canSave"
            @export="handleExport"
            @download-preview="downloadPreview"
            @download-production="downloadProduction"
            @update:projectName="handleProjectNameUpdate"
            @save="handleSaveDesign"
          />

          <p
            v-if="saveMessage"
            class="rounded-xl border border-emerald-500/40 bg-emerald-500/10 px-4 py-3 text-sm text-emerald-200"
          >
            {{ saveMessage }}
          </p>
          <p
            v-else-if="saveError"
            class="rounded-xl border border-rose-500/40 bg-rose-500/10 px-4 py-3 text-sm text-rose-200"
          >
            {{ saveError }}
          </p>

          <div class="rounded-2xl border border-slate-800/60 bg-slate-900/80 p-4 shadow-lg shadow-slate-950/40">
            <header class="flex items-center justify-between">
              <div>
                <h3 class="text-sm font-semibold uppercase tracking-wide text-slate-400">
                  Saved Projects
                </h3>
                <p class="mt-1 text-xs text-slate-500">Synced securely to Supabase</p>
              </div>
              <button
                type="button"
                class="rounded-lg border border-slate-700 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-slate-300 transition hover:border-sky-500/70 hover:text-sky-200 disabled:cursor-not-allowed disabled:border-slate-700/60 disabled:text-slate-500"
                :disabled="isLibraryLoading"
                @click="fetchDesigns"
              >
                {{ isLibraryLoading ? "Refreshing…" : "Refresh" }}
              </button>
            </header>

            <div v-if="isLibraryLoading" class="mt-4 text-sm text-slate-400">
              Loading your library…
            </div>
            <div v-else-if="!designs.length" class="mt-4 text-sm text-slate-500">
              Nothing saved yet—hit “Save to Library” once you love your design.
            </div>
            <ul v-else class="mt-4 space-y-3">
              <li
                v-for="design in designs"
                :key="design.id"
                class="flex items-center justify-between gap-4 rounded-xl border border-slate-800/70 bg-slate-950/70 px-3 py-3"
              >
                <div>
                  <p class="text-sm font-semibold text-slate-100">{{ design.name }}</p>
                  <p class="text-xs text-slate-500">
                    Updated {{ formatTimestamp(design.updatedAt) }}
                  </p>
                </div>
                <a
                  v-if="design.previewUrl"
                  :href="design.previewUrl"
                  target="_blank"
                  rel="noopener"
                  class="text-xs font-semibold uppercase tracking-wide text-sky-400 transition hover:text-sky-200"
                >
                  Preview
                </a>
              </li>
            </ul>
          </div>
        </div>

        <div class="flex flex-col gap-6">
          <div class="rounded-3xl border border-slate-800/60 bg-linear-to-br from-slate-900 via-slate-950 to-black p-6 shadow-2xl shadow-slate-950/60">
            <DesignerCanvas
              :size="displaySize"
              :background-color="selectedTemplate.backgroundColor"
              :register-canvas="registerCanvas"
              :unregister-canvas="unregisterCanvas"
            />
            <p class="mt-4 text-sm text-slate-400">
              Safe zone and bleed guides update automatically when you switch
              templates. Use the toolbar to layer text, shapes, and imagery inside the
              circular boundary.
            </p>
          </div>
        </div>
      </section>
    </div>
  </main>
</template>
