<script setup lang="ts">
import { usePage } from "@inertiajs/vue3";
import { computed, inject, ref, watch } from "vue";

interface SeoValue {
  title?: string | null;
  description?: string | null;
  robots?: string | null;
}

interface FieldDefinition {
  name: string;
  label: string;
  [key: string]: unknown;
}

const props = defineProps<{
  field: FieldDefinition;
  modelValue?: SeoValue | null;
  error?: string;
  currentLocale?: string | null;
}>();

const emit = defineEmits<{
  "update:modelValue": [value: SeoValue];
}>();

const page = usePage<{
  publicUrl?: string;
  seoSettings?: {
    site_name?: string;
    separator?: string;
    favicon_url?: string | null;
  };
  record?: Record<string, unknown>;
}>();

// Live form values provided by Form.vue — used to show the page title
// as the SEO title fallback when the SEO title field is empty.
const formValues = inject<Record<string, unknown>>("builderFormValues", {});

const normalized = computed<SeoValue>(() => ({
  title: props.modelValue?.title ?? "",
  description: props.modelValue?.description ?? "",
  robots: props.modelValue?.robots ?? "index",
}));

const localTitle = ref<string>((normalized.value.title as string) ?? "");
const localDescription = ref<string>(
  (normalized.value.description as string) ?? "",
);
const localRobots = ref<string>((normalized.value.robots as string) ?? "index");

watch(
  () => props.modelValue,
  (val) => {
    localTitle.value = val?.title ?? "";
    localDescription.value = val?.description ?? "";
    localRobots.value = val?.robots ?? "index";
  },
);

function emitUpdate(): void {
  emit("update:modelValue", {
    title: localTitle.value || null,
    description: localDescription.value || null,
    robots: localRobots.value || "index",
  });
}

const rawPublicUrl = computed<string>(
  () => page.props.publicUrl ?? "https://example.com",
);

// Strip protocol for display: "https://example.com" → "example.com"
const displayDomain = computed<string>(() =>
  rawPublicUrl.value.replace(/^https?:\/\//, "").replace(/\/$/, ""),
);

const currentSlug = computed<string | null>(() => {
  const live = formValues.slug;
  if (typeof live === "string" && live) return live;
  return (page.props.record?.slug as string | null) ?? null;
});

const displayUrl = computed<string>(() => {
  const slug = currentSlug.value;
  return slug ? `${displayDomain.value} › ${slug}` : displayDomain.value;
});

const siteName = computed<string>(
  () => page.props.seoSettings?.site_name ?? "",
);

const faviconUrl = computed<string | null>(
  () => page.props.seoSettings?.favicon_url ?? null,
);

const separator = computed<string>(
  () => page.props.seoSettings?.separator ?? " | ",
);

// Live page title fallback: reads the sibling "name" or "title" field from
// the parent form in real time so the preview updates as the user types.
const pageTitleFallback = computed<string>(() => {
  const v = formValues.name ?? formValues.title ?? "";
  return typeof v === "string" ? v : "";
});

const previewTitle = computed<string>(() => {
  const base = localTitle.value || pageTitleFallback.value || "Page Title";
  return siteName.value ? `${base}${separator.value}${siteName.value}` : base;
});

const previewDescription = computed<string>(() => {
  const desc = localDescription.value;
  return desc ? (desc.length > 160 ? desc.slice(0, 160) + "…" : desc) : "";
});

const titleLength = computed<number>(() => localTitle.value.length);
const descLength = computed<number>(() => localDescription.value.length);

function titleCounterClass(): string {
  const n = titleLength.value;
  if (n >= 50 && n <= 60) return "text-green-600";
  if (n > 70) return "text-red-600";
  return "text-amber-600";
}

function descCounterClass(): string {
  const n = descLength.value;
  if (n >= 150 && n <= 160) return "text-green-600";
  if (n > 170) return "text-red-600";
  return "text-amber-600";
}

const robotsOptions = [
  { value: "index", label: "index, follow" },
  { value: "noindex", label: "noindex, follow" },
  { value: "nofollow", label: "index, nofollow" },
  { value: "noindex,nofollow", label: "noindex, nofollow" },
  { value: "noarchive", label: "noarchive" },
  { value: "nosnippet", label: "nosnippet" },
];
</script>

<template>
  <div class="space-y-4">
    <!-- Google SERP Preview -->
    <div class="space-y-2">
      <p class="text-sm font-medium leading-none">SEO Preview</p>
      <div
        class="inline-block w-full max-w-[600px] rounded-lg border bg-white p-3"
      >
        <div class="space-y-0.5">
          <!-- Favicon + domain breadcrumb row -->
          <div class="flex items-center gap-1.5">
            <img
              v-if="faviconUrl"
              :src="faviconUrl"
              alt=""
              class="size-4 shrink-0 rounded-full object-cover"
            />
            <div
              v-else
              class="flex size-4 shrink-0 items-center justify-center rounded-full bg-[#f1f3f4]"
            >
              <div class="size-2.5 rounded-sm bg-[#bdc1c6]" />
            </div>
            <div class="min-w-0">
              <div class="truncate text-xs text-[#4d5156]">
                {{ displayUrl }}
              </div>
            </div>
          </div>
          <!-- Title -->
          <div class="truncate text-sm font-normal text-[#1a0dab]">
            {{
              previewTitle.length > 60
                ? previewTitle.slice(0, 60) + "…"
                : previewTitle
            }}
          </div>
          <!-- Description -->
          <div class="line-clamp-2 text-xs leading-relaxed text-[#4d5156]">
            {{ previewDescription || "No description set…" }}
          </div>
        </div>
      </div>
    </div>

    <!-- SEO Title -->
    <div class="space-y-1.5">
      <div class="flex items-center justify-between">
        <label
          :for="`${field.name}-title`"
          class="text-sm font-medium leading-none"
        >
          SEO Title
        </label>
        <span
          class="text-xs"
          :class="
            titleLength > 0 ? titleCounterClass() : 'text-muted-foreground'
          "
        >
          {{ titleLength }} / 60
        </span>
      </div>
      <input
        :id="`${field.name}-title`"
        v-model="localTitle"
        type="text"
        autocomplete="off"
        class="border-input bg-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border px-3 py-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1"
        @input="emitUpdate"
      />
      <p v-if="error" class="text-xs text-destructive">{{ error }}</p>
      <p class="text-xs text-muted-foreground">
        Aim for 50–60 characters for best search engine display.
      </p>
    </div>

    <!-- Meta Description -->
    <div class="space-y-1.5">
      <div class="flex items-center justify-between">
        <label
          :for="`${field.name}-description`"
          class="text-sm font-medium leading-none"
        >
          Meta Description
        </label>
        <span
          class="text-xs"
          :class="descLength > 0 ? descCounterClass() : 'text-muted-foreground'"
        >
          {{ descLength }} / 160
        </span>
      </div>
      <textarea
        :id="`${field.name}-description`"
        v-model="localDescription"
        rows="3"
        class="border-input bg-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1"
        @input="emitUpdate"
      />
      <p class="text-xs text-muted-foreground">
        Aim for 150–160 characters for best search engine display.
      </p>
    </div>

    <!-- Robots -->
    <div class="space-y-1.5">
      <label
        :for="`${field.name}-robots`"
        class="text-sm font-medium leading-none"
      >
        Robots
      </label>
      <select
        :id="`${field.name}-robots`"
        v-model="localRobots"
        class="border-input bg-background ring-offset-background focus-visible:ring-ring flex h-9 w-full rounded-md border px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1"
        @change="emitUpdate"
      >
        <option
          v-for="opt in robotsOptions"
          :key="opt.value"
          :value="opt.value"
        >
          {{ opt.label }}
        </option>
      </select>
    </div>
  </div>
</template>
