<template>
  <!-- Object inside an array item: render fields directly (card already has a header) -->
  <div v-if="kind === 'object' && bare" class="space-y-3">
    <AdminField
      v-for="k in objectKeys"
      :key="k"
      :parent="value"
      :field="k"
      :depth="(depth ?? 0) + 1"
    />
  </div>

  <!-- Object: collapsible section -->
  <details
    v-else-if="kind === 'object'"
    class="border border-gray-200 rounded-xl bg-white"
    :open="(depth ?? 0) < 1 && field !== 'meta'"
  >
    <summary
      class="cursor-pointer select-none px-4 py-2.5 font-semibold text-sm text-[#3C393D] flex items-center gap-2"
    >
      <span>{{ displayLabel }}</span>
      <span
        v-if="value.__component"
        class="text-[10px] font-normal bg-gray-100 text-gray-400 rounded-full px-2 py-0.5"
        >{{ value.__component }}</span
      >
    </summary>
    <div class="px-4 pb-4 space-y-3 border-t border-gray-100 pt-3">
      <AdminField
        v-for="k in objectKeys"
        :key="k"
        :parent="value"
        :field="k"
        :depth="(depth ?? 0) + 1"
      />
    </div>
  </details>

  <!-- Array: item list with add/remove/reorder -->
  <div v-else-if="kind === 'array'" class="space-y-2">
    <p class="text-sm font-semibold text-[#3C393D]">
      {{ displayLabel }}
      <span class="text-xs font-normal text-gray-400">({{ value.length }})</span>
    </p>
    <template v-for="(item, i) in value" :key="i">
      <!-- Nesne öğeler: açılır-kapanır kart -->
      <details
        v-if="item !== null && typeof item === 'object'"
        class="border border-gray-200 rounded-xl bg-[#fafbfc] group"
      >
        <summary
          class="flex items-center gap-1.5 px-3 py-2 text-xs text-gray-600 cursor-pointer select-none list-none"
        >
          <span
            class="text-gray-400 transition-transform group-open:rotate-90 shrink-0"
            >▶</span
          >
          <span class="font-semibold truncate text-[13px]">{{
            itemTitle(item, i)
          }}</span>
          <span class="flex-1"></span>
          <button
            class="px-1.5 py-0.5 rounded hover:bg-gray-200 cursor-pointer disabled:opacity-30"
            :disabled="i === 0"
            title="Yukarı taşı"
            @click.stop.prevent="move(i, -1)"
          >
            ▲
          </button>
          <button
            class="px-1.5 py-0.5 rounded hover:bg-gray-200 cursor-pointer disabled:opacity-30"
            :disabled="i === value.length - 1"
            title="Aşağı taşı"
            @click.stop.prevent="move(i, 1)"
          >
            ▼
          </button>
          <button
            class="px-1.5 py-0.5 rounded text-red-500 hover:bg-red-50 cursor-pointer"
            title="Sil"
            @click.stop.prevent="removeAt(i)"
          >
            Sil
          </button>
        </summary>
        <div class="p-3 border-t border-gray-100">
          <AdminField
            :parent="value"
            :field="i"
            :depth="(depth ?? 0) + 1"
            bare
          />
        </div>
      </details>

      <!-- Basit (metin/sayı) öğeler: tek satır -->
      <div v-else class="flex items-center gap-1.5">
        <div class="flex-1 min-w-0">
          <AdminField
            :parent="value"
            :field="i"
            :depth="(depth ?? 0) + 1"
            bare
          />
        </div>
        <button
          class="px-1.5 py-0.5 rounded text-xs text-gray-400 hover:bg-gray-200 cursor-pointer disabled:opacity-30"
          :disabled="i === 0"
          title="Yukarı taşı"
          @click="move(i, -1)"
        >
          ▲
        </button>
        <button
          class="px-1.5 py-0.5 rounded text-xs text-gray-400 hover:bg-gray-200 cursor-pointer disabled:opacity-30"
          :disabled="i === value.length - 1"
          title="Aşağı taşı"
          @click="move(i, 1)"
        >
          ▼
        </button>
        <button
          class="px-1.5 py-0.5 rounded text-xs text-red-400 hover:bg-red-50 cursor-pointer"
          title="Sil"
          @click="removeAt(i)"
        >
          Sil
        </button>
      </div>
    </template>
    <button
      class="w-full border border-dashed border-gray-300 rounded-xl py-2 text-sm text-gray-500 hover:border-[#3FA0C7] hover:text-[#3FA0C7] cursor-pointer"
      @click="addItem"
    >
      ＋ Ekle
    </button>
  </div>

  <!-- Primitive inside an array item (no label of its own) -->
  <div v-else-if="bare">
    <component :is="renderPrimitive" />
  </div>

  <!-- Primitive field -->
  <div v-else class="space-y-1">
    <label class="block text-xs font-medium text-gray-500">
      {{ displayLabel }}
    </label>
    <component :is="renderPrimitive" />
  </div>
</template>

<script setup lang="ts">
import { computed, h } from "vue";
import { useMediaPicker } from "@/composables/useMediaPicker";

defineOptions({ name: "AdminField" });

const mediaPicker = useMediaPicker();

const props = defineProps<{
  parent: any;
  field: string | number;
  depth?: number;
  bare?: boolean;
}>();

const READONLY_KEYS = new Set(["__component", "id", "slug", "locale", "type"]);

const LABELS: Record<string, string> = {
  title: "Başlık",
  subtitle: "Alt Başlık",
  description: "Açıklama",
  excerpt: "Özet",
  text: "Metin",
  content: "İçerik",
  image: "Görsel",
  images: "Görseller",
  src: "Görsel Yolu",
  alt: "Görsel Açıklaması (alt)",
  price: "Fiyat",
  name: "Ad",
  fullName: "Ad Soyad",
  items: "Öğeler",
  categories: "Kategoriler",
  components: "Sayfa Bölümleri",
  meta: "SEO Ayarları (Gelişmiş)",
  keywords: "Anahtar Kelimeler",
  canonical: "Canonical URL",
  author: "Yazar",
  robots: "Robots",
  enabled: "Aktif",
  startDate: "Başlangıç Tarihi",
  endDate: "Bitiş Tarihi",
  discount: "İndirim",
  rules: "Kurallar",
  tags: "Etiketler",
  buttons: "Butonlar",
  button: "Buton",
  link: "Bağlantı",
  url: "URL",
  href: "Bağlantı (href)",
  label: "Etiket",
  plates: "Tabak Görselleri",
  parent: "Üst Kategori",
  phone: "Telefon",
  email: "E-posta",
  address: "Adres",
  testimonials: "Yorumlar",
  comment: "Yorum",
  rating: "Puan",
  locale: "Dil",
  gallery: "Galeri",
  video: "Video",
  poster: "Kapak Görseli",
  order: "Sıra",
  badge: "Rozet",
  icon: "İkon",
  list: "Liste",
  features: "Özellikler",
};

const value = computed(() => props.parent[props.field]);

const kind = computed(() => {
  const v = value.value;
  if (Array.isArray(v)) return "array";
  if (v !== null && typeof v === "object") return "object";
  return "primitive";
});

const displayLabel = computed(() => {
  const f = props.field;
  if (typeof f === "number") return `Öğe ${f + 1}`;
  if (LABELS[f]) return LABELS[f];
  // camelCase / kebab-case -> Title Case
  return String(f)
    .replace(/[-_]/g, " ")
    .replace(/([a-z])([A-Z])/g, "$1 $2")
    .replace(/^./, (c) => c.toUpperCase());
});

const objectKeys = computed(() => {
  const keys = Object.keys(value.value).filter((k) => k !== "__component");
  // Meta/SEO en sona
  return keys.sort((a, b) => (a === "meta" ? 1 : b === "meta" ? -1 : 0));
});

function stripHtml(s: string) {
  return s.replace(/<[^>]*>/g, "");
}

const SECTION_LABELS: Record<string, string> = {
  "sections.hero": "Hero (Giriş)",
  "sections.highlight": "Öne Çıkanlar",
  "sections.banner": "Banner",
  "sections.parallax": "Parallax Görsel",
  "sections.overview": "Genel Bakış",
  "sections.cta": "Sipariş Çağrısı (CTA)",
  "sections.gallery": "Galeri",
  "sections.testimonials": "Müşteri Yorumları",
  "sections.breakfast": "Kahvaltı Bölümü",
  "sections.contact": "İletişim Formu",
};

function itemTitle(item: any, i: number) {
  if (item && typeof item === "object" && item.__component) {
    return SECTION_LABELS[item.__component] ?? item.__component;
  }
  if (item && typeof item === "object") {
    const t = item.title || item.name || item.label || item.alt || item.fullName;
    if (typeof t === "string" && t.trim()) return stripHtml(t).slice(0, 60);
  }
  if (typeof item === "string" && item.trim()) return stripHtml(item).slice(0, 60);
  return `Öğe ${i + 1}`;
}

function move(i: number, dir: number) {
  const arr = value.value;
  const j = i + dir;
  [arr[i], arr[j]] = [arr[j], arr[i]];
}

function removeAt(i: number) {
  if (!confirm(`"${itemTitle(value.value[i], i)}" silinsin mi?`)) return;
  value.value.splice(i, 1);
}

function emptied(v: any): any {
  if (Array.isArray(v)) return v.length ? [emptied(v[0])] : [];
  if (v !== null && typeof v === "object") {
    const out: any = {};
    for (const k of Object.keys(v)) {
      // Yapıyı koru: __component gibi anahtarlar aynen kalsın
      out[k] = k.startsWith("__") || READONLY_KEYS.has(k) ? v[k] : emptied(v[k]);
    }
    return out;
  }
  if (typeof v === "string") return "";
  if (typeof v === "number") return 0;
  if (typeof v === "boolean") return v;
  return v;
}

function addItem() {
  const arr = value.value;
  if (arr.length) {
    arr.push(emptied(arr[arr.length - 1]));
  } else {
    arr.push("");
  }
}

// ---- primitive rendering ----

const isReadonly = computed(
  () => typeof props.field === "string" && READONLY_KEYS.has(props.field),
);

function stringKind(s: string): "date" | "image" | "long" | "bool" | "text" {
  if (/^(true|false)$/i.test(s)) return "bool";
  if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return "date";
  if (/^(\/|https?:\/\/)[^\s]+\.(webp|jpe?g|png|svg|gif|avif|heic|heif)$/i.test(s))
    return "image";
  if (s.length > 90 || s.includes("\n")) return "long";
  return "text";
}

const inputCls =
  "w-full border border-gray-300 rounded-lg px-3 py-2 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-[#3FA0C7] disabled:bg-gray-100 disabled:text-gray-400";

const renderPrimitive = () => {
  const v = value.value;
  const set = (nv: any) => (props.parent[props.field] = nv);

  if (typeof v === "boolean") {
    return h("label", { class: "flex items-center gap-2 cursor-pointer" }, [
      h("input", {
        type: "checkbox",
        checked: v,
        class: "w-4 h-4 accent-[#3FA0C7]",
        onChange: (e: Event) => set((e.target as HTMLInputElement).checked),
      }),
      h("span", { class: "text-sm" }, v ? "Açık" : "Kapalı"),
    ]);
  }

  if (typeof v === "number") {
    return h("input", {
      type: "number",
      value: v,
      disabled: isReadonly.value,
      class: inputCls,
      onInput: (e: Event) =>
        set(Number((e.target as HTMLInputElement).value) || 0),
    });
  }

  const s = String(v ?? "");
  const sk = typeof v === "string" ? stringKind(s) : "text";

  if (sk === "bool" && !isReadonly.value) {
    // "True"/"False" gibi string boolean'lar — orijinal yazımı koru
    const isTrue = /^true$/i.test(s);
    const cap = s[0] === s[0]?.toUpperCase();
    return h(
      "select",
      {
        value: isTrue ? "on" : "off",
        class: inputCls + " cursor-pointer",
        onChange: (e: Event) => {
          const on = (e.target as HTMLSelectElement).value === "on";
          set(cap ? (on ? "True" : "False") : on ? "true" : "false");
        },
      },
      [
        h("option", { value: "on" }, "Açık"),
        h("option", { value: "off" }, "Kapalı"),
      ],
    );
  }

  if (sk === "date" && !isReadonly.value) {
    return h("input", {
      type: "date",
      value: s,
      class: inputCls,
      onInput: (e: Event) => set((e.target as HTMLInputElement).value),
    });
  }

  if (sk === "image") {
    return h("div", { class: "flex items-center gap-3" }, [
      h("img", {
        src: s,
        class:
          "w-14 h-14 rounded-lg object-cover border border-gray-200 bg-gray-50 shrink-0",
        loading: "lazy",
        onError: (e: Event) =>
          ((e.target as HTMLImageElement).style.opacity = "0.2"),
      }),
      h("input", {
        type: "text",
        value: s,
        disabled: isReadonly.value,
        class: inputCls + " font-mono text-xs",
        onInput: (e: Event) => set((e.target as HTMLInputElement).value),
      }),
      isReadonly.value
        ? null
        : h(
            "button",
            {
              type: "button",
              title: "Galeriden seç veya yükle",
              class:
                "shrink-0 text-xs font-semibold border border-gray-300 hover:border-[#3FA0C7] hover:text-[#3FA0C7] rounded-lg px-3 py-2 cursor-pointer",
              onClick: () => mediaPicker.open((url) => set(url)),
            },
            "🖼 Galeri",
          ),
    ]);
  }

  if (sk === "long") {
    const rows = Math.min(8, Math.max(3, Math.ceil(s.length / 80)));
    return h("textarea", {
      value: s,
      rows,
      disabled: isReadonly.value,
      class: inputCls + " resize-y leading-relaxed",
      onInput: (e: Event) => set((e.target as HTMLTextAreaElement).value),
    });
  }

  return h("input", {
    type: "text",
    value: s,
    disabled: isReadonly.value,
    class: inputCls,
    onInput: (e: Event) => set((e.target as HTMLInputElement).value),
  });
};
</script>
