<script setup lang="ts">
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 { useSlipmatDesigner } from "~/composables/useSlipmatDesigner";
import type { ExportedDesign } from "~/composables/useSlipmatDesigner";

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 DESIGN_PRICE_USD = 39.99;

const { user } = useAuth();
const loginModal = useLoginModal();

const isCheckoutPending = ref(false);
const checkoutError = ref<string | null>(null);
const lastExportedDesign = ref<ExportedDesign | null>(null);

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

const handleExport = async () => {
  const result = await exportDesign();
  if (result) {
    lastExportedDesign.value = result;
  }
};

const handleCheckout = async () => {
  if (!process.client) {
    return;
  }

  if (!user.value) {
    loginModal.value = true;
    return;
  }

  checkoutError.value = null;
  isCheckoutPending.value = true;

  try {
    let exportResult = await exportDesign();
    if (!exportResult) {
      exportResult = lastExportedDesign.value;
    }
    if (!exportResult) {
      throw new Error("Unable to export the current design. Please try again.");
    }
    lastExportedDesign.value = exportResult;

    const designId =
      typeof crypto !== "undefined" && "randomUUID" in crypto
        ? crypto.randomUUID()
        : `design-${Date.now()}`;

    const successUrlTemplate = `${window.location.origin}/checkout/success?session_id={CHECKOUT_SESSION_ID}`;
    const cancelUrl = window.location.href;

    const session = await $fetch<{ id: string; url?: string | null }>("/api/checkout.session", {
      method: "POST",
      body: {
        designId,
        templateId: exportResult.templateId,
        designName: templateLabel.value,
        amount: DESIGN_PRICE_USD,
        currency: "usd",
        successUrl: successUrlTemplate,
        cancelUrl,
        customerEmail: user.value?.email,
      },
    });

    if (!session?.id) {
      throw new Error("Stripe session could not be created.");
    }

    if (session.url) {
      window.location.href = session.url;
      return;
    }

    const fallbackRedirect = successUrlTemplate.replace("{CHECKOUT_SESSION_ID}", session.id);
    window.location.href = fallbackRedirect;
  } catch (err: any) {
    console.error("Checkout failed", err);
    checkoutError.value = err?.message ?? "Unable to start checkout. Please try again.";
  } finally {
    isCheckoutPending.value = false;
  }
};
</script>

<template>
  <main class="min-h-screen bg-slate-950 pb-16 text-slate-100">
    <AppNavbar />
    <div class="mx-auto max-w-6xl px-4 pt-12 sm:px-6 lg:px-8">
      <header 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>
      </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"
            :is-checkout-pending="isCheckoutPending"
            :checkout-price="DESIGN_PRICE_USD"
            :checkout-error="checkoutError"
            @export="handleExport"
            @download-preview="downloadPreview"
            @download-production="downloadProduction"
            @checkout="handleCheckout"
          />
        </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>
