<script setup>
import MediaPickerModal from "@/components/MediaPickerModal.vue";
import PublishDraftActions from "@/components/PublishDraftActions.vue";
import { useAuthStore } from "@/stores/authStore";
import { useProgramStore } from "@/stores/programStore";
import { storeToRefs } from "pinia";
import SlugConflictDialog from "@/components/SlugConflictDialog.vue";
import { getSlugConflictPayload } from "@/composables/useStoreHelpers";
import { computed, provide, ref } from "vue";
import { useRouter } from "vue-router";
import AccordionSection from "@/components/AccordionSection.vue";
import AccordionExpandToggle from "@/components/AccordionExpandToggle.vue";
import {
  createAccordionGroup,
  usePanelIn,
} from "@/composables/useAccordionGroup";
import SeoFields from "@/components/SeoFields.vue";
import BasicProgramForm from "./BasicProgramForm.vue";
import ProgramDetailsForm from "./ProgramDetailsForm.vue";
import BottomSliderForm from "@/components/BottomSliderForm.vue";
import AiFeatureForm from "@/components/AiFeatureForm.vue";
import TestimonialBannerForm from "@/components/TestimonialBannerForm.vue";

const router = useRouter();
const programStore = useProgramStore();
const authStore = useAuthStore();
const { user: authUser } = storeToRefs(authStore);
const saving = computed(() => programStore.saving);
const saveAction = ref(null);

const basicFormRef = ref(null);
const detailsFormRef = ref(null);
const bottomSliderFormRef = ref(null);
const aiFeatureFormRef = ref(null);
const testimonialBannerFormRef = ref(null);
const showSlugConflictDialog = ref(false);
const slugConflict = ref(null);
const pendingPayload = ref(null);

// SEO title/meta live on the translation. Owned here so the panel renders last,
// after every other form section. Create flow is English-only, so it starts empty.
const seo = ref({ seo_title: "", seo_description: "" });

// Shared accordion state for every section component below (basic info, details,
// sliders, SEO, …). First section starts open; "Expand all" opens the rest.
// No seed key: every section starts collapsed.
const programAccordion = createAccordionGroup();
provide("activeProgramPanel", programAccordion);
const seoPanel = usePanelIn(programAccordion, "seo-0");

// Media picker state
const showMediaPicker = ref(false);
const currentImageField = ref({
  fieldKey: null,
  mediaCategory: "program_sliders",
  multiple: true,
  index: null,
});

// Media picker handler
const handleMediaPickerOpen = (payload) => {
  currentImageField.value = {
    fieldKey: payload.fieldKey,
    mediaCategory: payload.mediaCategory || "program_sliders",
    multiple: !!payload.multiple,
    index: payload.index ?? null,
  };
  showMediaPicker.value = true;
};

// Handle media selection callback
const handleMediaSelect = (selectedMedia) => {
  const { fieldKey, multiple, index } = currentImageField.value;

  if (!fieldKey) {
    showMediaPicker.value = false;
    return;
  }

  // Extract URLs from selected media
  let imageUrls = [];
  if (multiple) {
    const mediaArray = Array.isArray(selectedMedia)
      ? selectedMedia
      : [selectedMedia];
    imageUrls = mediaArray.filter((m) => m?.url).map((m) => m.url);
  } else if (selectedMedia?.url) {
    imageUrls = [selectedMedia.url];
  }

  // Bottom-slider robot image is owned by the BottomSliderForm component.
  if (fieldKey === "bottom_slider_robot") {
    bottomSliderFormRef.value?.setRobotImage?.(index, imageUrls[0] || "");
    showMediaPicker.value = false;
    return;
  }

  if (!detailsFormRef.value) {
    showMediaPicker.value = false;
    return;
  }

  // Update form data based on field key
  if (fieldKey === "sliderImages") {
    detailsFormRef.value.formData.sliders.sliderImages = imageUrls;
  } else if (fieldKey === "reverseSliderImages") {
    detailsFormRef.value.formData.sliders.reverseSliderImages = imageUrls;
  } else if (fieldKey === "program_icon") {
    basicFormRef.value.setFieldValue("program_icon", imageUrls[0] || "");
  } else if (fieldKey === "header_image") {
    basicFormRef.value.setFieldValue("header_image", imageUrls[0] || "");
  } else if (fieldKey === "gallery_slide_robot") {
    const slide = detailsFormRef.value.formData.gallery_slides?.[index];
    if (slide) slide.robot_image = imageUrls[0] || "";
  }

  // Close picker
  showMediaPicker.value = false;
  currentImageField.value = {
    fieldKey: null,
    mediaCategory: "program_sliders",
    multiple: true,
    index: null,
  };
};

async function handleSave(asDraft = false) {
  if (saving.value) return;
  saveAction.value = asDraft ? "draft" : "publish";
  // 1. Get Values
  const basicValues = basicFormRef.value?.values;
  const detailsRaw = detailsFormRef.value?.values;
  const detailValues = detailsRaw?.value || detailsRaw;

  if (!basicValues) {
    saveAction.value = null;
    alert("Please fill in the Basic Information");
    return;
  }

  // 2. Validate Basic Form
  const basicValidation = await basicFormRef.value?.validateForm?.();
  if (basicValidation && Object.keys(basicValidation).length > 0) {
    saveAction.value = null;
    return;
  }

  let payload = null;

  try {
    const detailsData = detailValues || {};

    // 3. Construct Payload
    payload = {
      ...basicValues,
      slug: basicFormRef.value.computedSlug, // Use the computed slug logic
      status: asDraft ? "draft" : "publish",
      seo_title: seo.value.seo_title || "",
      seo_description: seo.value.seo_description || "",
      is_global: authUser.value?.data?.role === "super_admin" ? true : false,
      is_required_for_translation: !!basicValues.is_required_for_translation,
      program_details: (() => {
        const details = { ...detailsData };
        delete details.logo;
        delete details.logos;
        details.bottom_sliders = bottomSliderFormRef.value?.getValues?.() || [];
        details.feature_section = aiFeatureFormRef.value?.getValues?.() ?? null;
        details.testimonials_section =
          testimonialBannerFormRef.value?.getValues?.() ?? null;
        return details;
      })(), // Nest the accordion data
      // Handle ID mapping for images if your API needs it explicitly,
      // otherwise passing the URL strings (as done in Activity) usually suffices.
    };

    // Map logo to the new root program_icon field
    payload.program_icon = basicFormRef.value.getLogo() || "";

    // Remove temp file objects if they exist in basicValues,
    // usually the form handles URL strings, so this is fine.

    await submitProgram(payload);
  } catch (err) {
    const conflict = getSlugConflictPayload(err);
    if (conflict?.code === "slug_restorable") {
      slugConflict.value = conflict;
      pendingPayload.value = payload;
      showSlugConflictDialog.value = true;
      return;
    }
  } finally {
    saveAction.value = null;
  }
}

async function submitProgram(payload, restoreDeleted = false) {
  const body = { ...payload };
  if (restoreDeleted) {
    body.restore_deleted = true;
  }
  await programStore.createProgram(body);
  router.push("/programs");
}

async function confirmSlugRestore() {
  if (!pendingPayload.value) return;
  saveAction.value = "restore";
  try {
    await submitProgram(pendingPayload.value, true);
  } catch (err) {
    const conflict = getSlugConflictPayload(err);
    if (conflict) {
      slugConflict.value = conflict;
      showSlugConflictDialog.value = true;
    }
  } finally {
    saveAction.value = null;
    pendingPayload.value = null;
    slugConflict.value = null;
  }
}

function handleCancel() {
  router.push("/programs");
}
</script>

<template>
  <div class="program-page-layout">
    <div class="page-header">
      <div>
        <h1 class="page-title">Add New Program</h1>
        <p class="page-subtitle">Create a new learning program</p>
      </div>
      <VBtn
        variant="text"
        color="primary"
        prepend-icon="bx-arrow-back"
        :disabled="saving"
        @click="handleCancel"
      >
        Back
      </VBtn>
    </div>

    <div class="content-grid">
      <div class="main-content">
        <AccordionExpandToggle :group="programAccordion" />

        <BasicProgramForm
          ref="basicFormRef"
          :loading="saving"
          mode="create"
          lang-code="en"
          @cancel="handleCancel"
          @open-media-picker="handleMediaPickerOpen"
        />

        <div class="spacer"></div>

        <ProgramDetailsForm
          ref="detailsFormRef"
          :loading="saving"
          mode="create"
          lang-code="en"
          :slug="basicFormRef?.computedSlug"
          @cancel="handleCancel"
          @open-media-picker="handleMediaPickerOpen"
        />

        <BottomSliderForm
          ref="bottomSliderFormRef"
          :loading="saving"
          mode="create"
          panel-injection-key="activeProgramPanel"
          class="bottom-slider-attached"
          @open-media-picker="handleMediaPickerOpen"
        />

        <AiFeatureForm
          ref="aiFeatureFormRef"
          :loading="saving"
          mode="create"
        />

        <TestimonialBannerForm
          ref="testimonialBannerFormRef"
          :loading="saving"
          mode="create"
        />

        <VExpansionPanels
          v-model="seoPanel"
          variant="accordion"
          class="custom-accordion-panels seo-panels"
          style="margin-top: 8px"
          elevation="0"
        >
          <AccordionSection
            title="SEO Meta Tags"
            subtitle="Search engine title & description"
            icon="bx-search-alt"
            iconColorClass="icon-teal"
          >
            <SeoFields
              v-model:seo-title="seo.seo_title"
              v-model:seo-description="seo.seo_description"
              :disabled="saving"
            />
          </AccordionSection>
        </VExpansionPanels>
      </div>

      <div class="side-content">
        <div class="sticky-wrapper">
          <div class="sidebar-card">
            <h3 class="sidebar-title">Publish</h3>
            <p class="sidebar-text">Review and save your changes.</p>

            <PublishDraftActions
              :loading="saving"
              :loading-action="saveAction"
              @publish="handleSave(false)"
              @draft="handleSave(true)"
            />
          </div>
        </div>
      </div>
    </div>

    <MediaPickerModal
      v-model="showMediaPicker"
      :multiple="currentImageField.multiple"
      filter-type="image"
      :media-category="currentImageField.mediaCategory"
      @select="handleMediaSelect"
    />

    <SlugConflictDialog
      v-model:visible="showSlugConflictDialog"
      :conflict="slugConflict?.conflict"
      mode="restore_deleted"
      resource-label="program"
      @confirm="confirmSlugRestore"
    />
  </div>
</template>

<style scoped>
.program-page-layout {
  padding: 32px;
  max-width: 1300px;
  margin: 0 auto;
}
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}
.page-title {
  font-size: 28px;
  font-weight: 700;
  color: rgb(var(--v-theme-on-surface));
  margin: 0 0 4px 0;
  letter-spacing: -0.5px;
}
.page-subtitle {
  font-size: 15px;
  color: rgb(var(--v-theme-on-surface), 0.7);
  margin: 0;
}

.content-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 32px;
}
.main-content {
  display: flex;
  flex-direction: column;
}
.spacer {
  height: 24px;
}

/* Sticky Sidebar */
.side-content {
  height: 100%;
}
.sticky-wrapper {
  position: sticky;
  top: 105px;
  z-index: 10;
}
.sidebar-card {
  background: rgb(var(--v-theme-surface));
  border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 16px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.sidebar-title {
  font-size: 16px;
  font-weight: 700;
  color: rgb(var(--v-theme-on-surface));
  margin: 0 0 8px 0;
}
.sidebar-text {
  font-size: 13px;
  color: rgb(var(--v-theme-on-surface), 0.7);
  margin-bottom: 16px;
}

@media (max-width: 960px) {
  .content-grid {
    grid-template-columns: 1fr;
  }
  .sticky-wrapper {
    position: static;
  }
  .side-content {
    order: -1;
  }
  .program-page-layout {
    padding: 16px;
  }
}
</style>
