<script setup>
import ConfirmationDialog from "@/components/ConfirmationDialog.vue";
import EntityTranslationToolbar from "@/components/EntityTranslationToolbar.vue";
import MediaPickerModal from "@/components/MediaPickerModal.vue";
import OverlayLoader from "@/components/OverlayLoader.vue";
import PublishDraftActions from "@/components/PublishDraftActions.vue";
import TranslationSidebarCard from "@/components/TranslationSidebarCard.vue";
import UpdatePreviewDialog from "@/components/UpdatePreviewDialog.vue";
import { useAuthStore } from "@/stores/authStore";
import { useActivityStore } from "@/stores/activityStore";
import { useSettingStore } from "@/stores/settingStore";
import { storeToRefs } from "pinia";
import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from "vue";
import { useAppToast } from "@/composables/useAppToast";
import { useRoute, useRouter } from "vue-router";
import { languages } from "@/utils/languageCode";
import { dedupeTranslationFamily } from "@/utils/translationFamily";
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 BasicActivityForm from "./BasicActivityForm.vue";
import WorkshopDetailsForm from "./WorkshopDetailsForm.vue";
import AiFeatureForm from "@/components/AiFeatureForm.vue";

const router = useRouter();

const normalizeSlug = (s) =>
  (s ? s.toString().toUpperCase().replace(/[^A-Z0-9]/g, "") : "");
// Workshops that show the AI section on the public site (by normalized slug).
const AI_SECTION_SLUGS = ["CODING_CAMPS"].map(normalizeSlug);
const route = useRoute();
const activityStore = useActivityStore();
const authStore = useAuthStore();
const settingStore = useSettingStore();
const { user: authUser } = storeToRefs(authStore);
const { setting } = storeToRefs(settingStore);
const { success, error, info, warning } = useAppToast();

const saving = computed(() => activityStore.saving);
const loading = computed(() => activityStore.loading);
const isLoadingUpdatePreview = computed(
  () => activityStore.isLoadingUpdatePreview,
);
const isLoadingResetPreview = computed(
  () => activityStore.isLoadingResetPreview,
);
const suppressOverlay = ref(false);
const busy = computed(
  () =>
    (loading.value ||
      saving.value ||
      isLoadingUpdatePreview.value ||
      isLoadingResetPreview.value) &&
    !suppressOverlay.value,
);
const isSuperAdmin = computed(
  () => authUser.value?.data?.role === "super_admin",
);
const franchisePrimaryLanguageCode = computed(() => {
  const configured = setting.value?.general_settings?.language_code;
  const fallback = authUser.value?.data?.franchisee?.language;
  const code = (configured || fallback || "en").toString().toLowerCase();
  return code === "english" ? "en" : code;
});
const isEnglishReadOnlyForFranchise = computed(
  () =>
    !isSuperAdmin.value &&
    franchisePrimaryLanguageCode.value !== "en" &&
    activeLanguage.value === "en",
);

const selectedLanguageToAdd = ref(null);
const translating = ref(false);
const translationProgressMessage = ref("");
const saveAction = ref(null);
const isSaveInProgress = computed(() => saving.value && !!saveAction.value);
let translationMessageTimer = null;
const showRemoveTranslationDialog = ref(false);
const showUpdatePreviewDialog = ref(false);
const updatePreviewData = ref(null);
const updatePreviewContext = ref({
  activityId: null,
  language: "en",
  mode: "update",
});
const globalTranslationRequired = ref(false);
const activeLanguage = ref("en");
const activityByLanguage = ref({});
const translationTabs = ref([{ code: "en", label: "English" }]);
const languageStatuses = ref({ en: "draft" });

const activityFormRef = ref(null);
const workshopFormRef = ref(null);
const aiFeatureFormRef = ref(null);

// No seed key: every section starts collapsed.
const activityAccordion = createAccordionGroup();
provide("activeActivityPanel", activityAccordion);

const showMediaPicker = ref(false);
const currentImageField = ref({
  fieldKey: null,
  mediaCategory: "workshop_sliders",
  multiple: true,
  index: null,
});

const activeActivity = computed(
  () => activityByLanguage.value?.[activeLanguage.value] || null,
);

// SEO title/meta live on the translation (per language). Owned here so the panel
// renders last (after every other form component) and coordinates with the shared
// accordion state. Re-initialized whenever the active language/record changes.
const seo = ref({ seo_title: "", seo_description: "" });
watch(
  activeActivity,
  (next) => {
    seo.value = {
      seo_title: next?.seo_title || "",
      seo_description: next?.seo_description || "",
    };
  },
  { immediate: true },
);

const SEO_PANEL_KEY = "seo-0";
const seoPanel = usePanelIn(activityAccordion, SEO_PANEL_KEY);

// Show the AI section editor only for AI-enabled workshops (by slug).
const showAiSection = computed(() =>
  AI_SECTION_SLUGS.includes(normalizeSlug(activeActivity.value?.slug)),
);

const franchiseId = computed(
  () =>
    authUser.value?.data?.franchisee_id ||
    authUser.value?.data?.franchisee?.id ||
    "",
);
const currentStatusLabel = computed(() =>
  (languageStatuses.value?.[activeLanguage.value] || "draft").toUpperCase(),
);
const lastUpdatedLabel = computed(() => {
  const source = activeActivity.value;
  const lastUpdatedAt = source?.updated_at || source?.created_at;
  if (!lastUpdatedAt) return "N/A";

  const parsedDate = new Date(lastUpdatedAt);
  if (Number.isNaN(parsedDate.getTime())) return "N/A";

  return new Intl.DateTimeFormat(undefined, {
    year: "numeric",
    month: "short",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  }).format(parsedDate);
});
const previewUrl = computed(() => {
  const activityId = route.params.id;
  if (!activityId) return "";
  const base = import.meta.env.VITE_PREVIEW_URL || "";
  if (!base) return "";

  const normalizedBase = base.endsWith("/") ? base.slice(0, -1) : base;
  const url = new URL(`${normalizedBase}/workshops/${activityId}`);

  if (activeLanguage.value) {
    url.searchParams.set("lang", activeLanguage.value);
  }
  if (!isSuperAdmin.value && franchiseId.value) {
    url.searchParams.set("franchiseeId", franchiseId.value);
  }

  return url.toString();
});

const selectedLanguageLabel = computed(() => {
  const match = languages.find((item) => item.code === activeLanguage.value);
  return match?.name || activeLanguage.value?.toUpperCase() || "English";
});
const platformStatusMessage = computed(() => {
  const current = activeActivity.value;
  const english = activityByLanguage.value?.en;

  return (
    current?.platform_status_message || english?.platform_status_message || null
  );
});

const copyToClipboard = async (text) => {
  if (!text) return;

  try {
    await navigator.clipboard.writeText(text);
    success("Preview URL copied to clipboard.");
  } catch (_error) {
    error("Unable to copy URL. Please copy it manually.");
  }
};

const availableLanguageOptions = computed(() =>
  languages
    .filter(
      (item) => !translationTabs.value.find((tab) => tab.code === item.code),
    )
    .map((item) => ({ code: item.code, label: item.name })),
);

const enforceFranchiseLanguageTabs = () => {
  if (isSuperAdmin.value) return;

  const primaryCode = franchisePrimaryLanguageCode.value || "en";
  const primaryMatch = languages.find((item) => item.code === primaryCode);
  const nextTabs = [
    {
      code: primaryCode,
      label:
        primaryMatch?.name ||
        setting.value?.general_settings?.language_name ||
        primaryCode.toUpperCase(),
    },
  ];

  if (!activityByLanguage.value[primaryCode]) {
    const seed =
      activityByLanguage.value[primaryCode] ||
      activityByLanguage.value.en ||
      Object.values(activityByLanguage.value || {})[0];

    if (seed) {
      activityByLanguage.value[primaryCode] = {
        ...JSON.parse(JSON.stringify(seed)),
        id: null,
        parent_activities_id: seed?.parent_activities_id || seed?.id || null,
        language: primaryCode,
      };
      languageStatuses.value[primaryCode] =
        languageStatuses.value[primaryCode] || "draft";
    }
  }

  translationTabs.value = nextTabs;
  activeLanguage.value = primaryCode;
};

const canResetToGlobal = computed(() => {
  if (isSuperAdmin.value) return false;
  const current = activityByLanguage.value?.[activeLanguage.value];
  return !!current?.show_reset_to_global;
});
const canUpdateToLatestGlobal = computed(() => {
  if (isSuperAdmin.value) return false;
  const current = activityByLanguage.value?.[activeLanguage.value];
  return !!current?.show_update_to_latest_global;
});
const isLocallyModifiedTranslation = computed(() => {
  const current = activityByLanguage.value?.[activeLanguage.value];
  return !!current?.is_locally_modified;
});
const updatePreviewHasLocalChanges = computed(() => {
  const preview = updatePreviewData.value || {};
  return (
    !!preview?.has_local_changes || preview?.sync_state === "locally_modified"
  );
});
const updatePreviewWarning = computed(
  () =>
    updatePreviewData.value?.warning ||
    "Accepting this update will replace your current franchise content with the latest super admin version.",
);

const isUpdatePreviewModeReset = computed(
  () => updatePreviewContext.value?.mode === "reset",
);

const updatePreviewDialogTitle = computed(() =>
  isUpdatePreviewModeReset.value
    ? "Preview Reset to Global"
    : "Review Latest Super Admin Update",
);

const updatePreviewDialogDescription = computed(() =>
  isUpdatePreviewModeReset.value
    ? "Compare your franchise copy with the global source. Highlighted fields will change when you confirm."
    : "A newer global version is available. Please review the changes below. If you accept, your current franchise content for this language will be replaced.",
);

const updatePreviewDialogAcceptText = computed(() =>
  isUpdatePreviewModeReset.value ? "Confirm Reset" : "Accept Latest Update",
);

const updatePreviewDialogBanner = computed(() =>
  isUpdatePreviewModeReset.value
    ? "After you confirm, your franchise copy for this language will match the global version."
    : "",
);

const persistActiveDraft = () => {
  const current = activeActivity.value;
  if (!current) return;

  if (activityFormRef.value?.values) {
    const formValues = activityFormRef.value.values;
    current.title = formValues.title || current.title;
    current.slug = formValues.slug || current.slug;
    current.cw_program_id = formValues.cw_program_id || current.cw_program_id;
    current.is_enabled = !!formValues.is_enabled;
    current.is_required_for_translation =
      !!formValues.is_required_for_translation;
    current.activity_icon = formValues.activity_icon || "";
    current.activity_details = {
      ...(current.activity_details || {}),
      tag: formValues.tag || "",
      activity_name: formValues.activity_name || "",
      activity_heading: formValues.activity_heading || "",
      activity_description: formValues.activity_description || "",
      created_for: formValues.created_for || "",
      ideal_for_text: formValues.ideal_for_text || "",
      age: formValues.age || null,
      age_text: formValues.age_text || "",
      grade: formValues.grade || "",
      grade_text: formValues.grade_text || "",
      duration_heading: formValues.duration_heading || "",
      duration: formValues.duration || "",
      duration_text: formValues.duration_text || "",
      image: formValues.image || "",
      cta_button: formValues.cta_button || { text: "", url: "" },
      feature_section: aiFeatureFormRef.value?.getValues?.() ?? null,
    };
  }

  current.activity_details = {
    ...(current.activity_details || {}),
    workshop_details:
      workshopFormRef.value?.values ||
      current.activity_details?.workshop_details ||
      {},
  };

  current.seo_title = seo.value.seo_title ?? current.seo_title ?? "";
  current.seo_description =
    seo.value.seo_description ?? current.seo_description ?? "";
  current.language = activeLanguage.value;

  activityByLanguage.value[activeLanguage.value] = { ...current };
};

const normalizeActivityRow = (item = {}) => {
  const globalStatus =
    item.global_status ?? item.global_translation_status ?? null;
  const globalVersion =
    item.global_version ?? item.global_translation_version ?? null;
  const hasGlobalTranslation =
    item.has_global_translation ?? item.global_translation_exists ?? false;

  return {
    ...item,
    has_global_translation: !!hasGlobalTranslation,
    global_status: globalStatus,
    global_version: globalVersion,
    show_reset_to_global:
      item.show_reset_to_global ??
      (!!hasGlobalTranslation &&
        String(globalStatus || "").toLowerCase() === "publish"),
    show_update_to_latest_global:
      item.show_update_to_latest_global ?? !!item.is_outdated,
  };
};

const hydrateTranslationFamily = (rawFamily) => {
  const nextByLanguage = {};
  const nextStatuses = {};

  // Collapse duplicate language rows first: a language that renders fallback
  // content must never overwrite the row that owns that language.
  const family = dedupeTranslationFamily(rawFamily);

  family.forEach((rawItem) => {
    const item = normalizeActivityRow(rawItem);
    const code = item.language || "en";
    nextByLanguage[code] = { ...item };
    nextStatuses[code] =
      item.status || languageStatuses.value?.[code] || "draft";
  });

  activityByLanguage.value = nextByLanguage;
  languageStatuses.value = { ...nextStatuses };

  translationTabs.value = Object.keys(nextByLanguage)
    .map((code) => {
      const match = languages.find((lang) => lang.code === code);
      return { code, label: match?.name || code.toUpperCase() };
    })
    .sort((a, b) => (a.code === "en" ? -1 : b.code === "en" ? 1 : 0));
};

const loadTranslationFamily = async (options = {}) => {
  const { preferredLanguage = activeLanguage.value, currentRecord = null } =
    options;
  const currentId = route.params.id;
  if (!currentId && !currentRecord) return;

  let current = currentRecord || null;
  if (!current || !Array.isArray(current?.translation_family)) {
    const response = await activityStore.fetchActivityById(currentId, {
      language: preferredLanguage || "en",
    });
    current = response?.data?.data || response?.data || response || null;
  }
  if (!current) return;

  const family = Array.isArray(current?.translation_family)
    ? current.translation_family
    : [current];
  const englishEntry = family.find((item) => (item.language || "en") === "en");
  globalTranslationRequired.value = !!(
    englishEntry?.is_required_for_translation ??
    current?.is_required_for_translation
  );

  hydrateTranslationFamily(family);
  const availableCodes = Object.keys(activityByLanguage.value || {});
  const firstAvailableCode = availableCodes[0] || "en";
  const fallbackLanguage = current.language || firstAvailableCode;

  if (preferredLanguage && activityByLanguage.value?.[preferredLanguage]) {
    activeLanguage.value = preferredLanguage;
  } else if (fallbackLanguage && activityByLanguage.value?.[fallbackLanguage]) {
    activeLanguage.value = fallbackLanguage;
  } else {
    activeLanguage.value = firstAvailableCode;
  }
  enforceFranchiseLanguageTabs();
};

const handleLanguageTabChange = (langCode) => {
  if (langCode === activeLanguage.value) return;
  persistActiveDraft();
  activeLanguage.value = langCode;
};

const handleAddLanguage = () => {
  if (!selectedLanguageToAdd.value) return;
  persistActiveDraft();

  const code = selectedLanguageToAdd.value;
  if (!activityByLanguage.value[code]) {
    const english =
      activityByLanguage.value.en || Object.values(activityByLanguage.value)[0];
    activityByLanguage.value[code] = {
      ...(english || {}),
      id: null,
      parent_activities_id:
        english?.parent_activities_id || english?.id || null,
      language: code,
      is_global: isSuperAdmin.value,
      is_required_for_translation: globalTranslationRequired.value,
      activity_details: {
        ...(english?.activity_details || {}),
        workshop_details: JSON.parse(
          JSON.stringify(english?.activity_details?.workshop_details || {}),
        ),
      },
    };
    languageStatuses.value[code] = "draft";
  }

  if (!translationTabs.value.find((tab) => tab.code === code)) {
    const lang = languages.find((item) => item.code === code);
    translationTabs.value.push({
      code,
      label: lang?.name || code.toUpperCase(),
    });
  }

  activeLanguage.value = code;
  selectedLanguageToAdd.value = null;
};

const ensureTranslationRecordExists = async () => {
  const current = activeActivity.value;
  if (current?.id || activeLanguage.value === "en") return current;

  const englishSource =
    activityByLanguage.value.en || Object.values(activityByLanguage.value)[0];
  if (!englishSource?.id) return current;

  const lang = languages.find((item) => item.code === activeLanguage.value);
  const created = await activityStore.translateActivities({
    type: "activities",
    method: "manual",
    language: lang?.name || activeLanguage.value.toUpperCase(),
    "language-code": activeLanguage.value,
    activity_ids: [englishSource.id],
  });

  const next = created?.data?.translation_done?.[0];
  if (next?.id) {
    activityByLanguage.value[activeLanguage.value] = {
      ...activityByLanguage.value[activeLanguage.value],
      ...next,
    };
  }

  return activityByLanguage.value[activeLanguage.value];
};

const handleTranslateActiveLanguage = async () => {
  if (activeLanguage.value === "en") return;
  translating.value = true;
  suppressOverlay.value = true;
  startTranslationProgress();
  try {
    await ensureTranslationRecordExists();

    const englishSource =
      activityByLanguage.value.en || Object.values(activityByLanguage.value)[0];
    if (!englishSource?.id) return;

    const lang = languages.find((item) => item.code === activeLanguage.value);
    const translationResponse = await activityStore.translateActivities({
      type: "activities",
      method: "openAI",
      language: lang?.name || activeLanguage.value.toUpperCase(),
      "language-code": activeLanguage.value,
      activity_ids: [englishSource.id],
    });

    const exitMessages = translationResponse?.data?.translation_exit || [];
    if (translationResponse?.success === false) {
      error(
        translationResponse?.error ||
          "Unable to translate activity content right now.",
      );
      return;
    }

    if (exitMessages.length > 0) {
      warning(exitMessages[0]);
    }

    await loadTranslationFamily({ preferredLanguage: activeLanguage.value });
  } finally {
    translating.value = false;
    suppressOverlay.value = false;
    stopTranslationProgress();
  }
};

const handleRemoveActiveTranslation = async () => {
  if (!isSuperAdmin.value || activeLanguage.value === "en") return;
  showRemoveTranslationDialog.value = true;
};

const confirmRemoveActiveTranslation = async () => {
  const target = activityByLanguage.value?.[activeLanguage.value];
  const targetLanguage = activeLanguage.value;
  if (!target?.id) {
    delete activityByLanguage.value[activeLanguage.value];
    translationTabs.value = translationTabs.value.filter(
      (tab) => tab.code !== activeLanguage.value,
    );
    activeLanguage.value = "en";
    showRemoveTranslationDialog.value = false;
    return;
  }

  const response = await activityStore.deleteActivity(target.id, {
    params: { language: targetLanguage },
  });
  const apiMessage =
    response?.message ||
    response?.data?.message ||
    `Translation of this activity removed in ${targetLanguage.toUpperCase()}.`;
  const fallbackCurrent =
    activityByLanguage.value?.en ||
    Object.values(activityByLanguage.value || {})[0] ||
    null;
  await loadTranslationFamily({
    currentRecord: fallbackCurrent,
    preferredLanguage: "en",
  });
  activeLanguage.value = "en";
  showRemoveTranslationDialog.value = false;
  success(apiMessage);
};

const handleResetToGlobal = async () => {
  if (!canResetToGlobal.value) return;
  const target = activityByLanguage.value?.[activeLanguage.value];
  if (!target?.id) return;

  try {
    const response = await activityStore.fetchResetPreview(
      target.id,
      activeLanguage.value,
    );
    const preview = response?.data || {};
    updatePreviewData.value = preview;
    updatePreviewContext.value = {
      activityId: target.id,
      language: activeLanguage.value,
      mode: "reset",
    };
    showUpdatePreviewDialog.value = true;
  } catch (err) {
    error(
      err?.response?.data?.message ||
        "Unable to load reset preview right now.",
    );
  }
};

const handleUpdateToLatestGlobal = async () => {
  if (!canUpdateToLatestGlobal.value) return;
  const target = activityByLanguage.value?.[activeLanguage.value];
  if (!target?.id) return;

  try {
    const response = await activityStore.fetchUpdatePreview(
      target.id,
      activeLanguage.value,
    );
    const preview = response?.data || {};
    const changes = Array.isArray(preview?.changes) ? preview.changes : [];

    if (!preview?.update_available || changes.length === 0) {
      info(
        preview?.message ||
          "No differences were found between your current translation and the latest super admin version.",
      );
      return;
    }

    updatePreviewData.value = preview;
    updatePreviewContext.value = {
      activityId: target.id,
      language: activeLanguage.value,
      mode: "update",
    };
    showUpdatePreviewDialog.value = true;
  } catch (err) {
    error(
      err?.response?.data?.message ||
        "Unable to load update preview right now.",
    );
  }
};

const closeUpdatePreviewDialog = () => {
  showUpdatePreviewDialog.value = false;
  updatePreviewData.value = null;
  updatePreviewContext.value = {
    activityId: null,
    language: "en",
    mode: "update",
  };
};

const confirmResetToGlobalFromPreview = async () => {
  const activityId = updatePreviewContext.value?.activityId;
  const language = updatePreviewContext.value?.language || activeLanguage.value;
  if (!activityId) return;

  try {
    await activityStore.resetActivityToGlobal(activityId, language);
    closeUpdatePreviewDialog();

    const fallbackCurrent =
      activityByLanguage.value?.en ||
      Object.values(activityByLanguage.value || {})[0] ||
      null;
    await loadTranslationFamily({
      preferredLanguage: language,
      currentRecord: fallbackCurrent,
    });

    success("Activity reset to global successfully.");
  } catch (err) {
    error(
      err?.response?.data?.message ||
        "Unable to reset this activity to the global version.",
    );
  }
};

const acceptLatestUpdate = async () => {
  const activityId = updatePreviewContext.value?.activityId;
  const language = updatePreviewContext.value?.language || activeLanguage.value;
  if (!activityId) return;

  try {
    await activityStore.updateActivityToLatestGlobal(activityId, language);
    closeUpdatePreviewDialog();

    const fallbackCurrent =
      activityByLanguage.value?.en ||
      Object.values(activityByLanguage.value || {})[0] ||
      null;
    await loadTranslationFamily({
      preferredLanguage: language,
      currentRecord: fallbackCurrent,
    });

    success("Latest super admin update applied successfully.");
  } catch (err) {
    error(
      err?.response?.data?.message ||
        "Unable to apply latest super admin update.",
    );
  }
};

const handleUpdatePreviewDialogConfirm = async () => {
  if (updatePreviewContext.value?.mode === "reset") {
    await confirmResetToGlobalFromPreview();
    return;
  }
  await acceptLatestUpdate();
};

async function handleSave(asDraft = false) {
  if (isEnglishReadOnlyForFranchise.value) return;
  if (saving.value) return;
  saveAction.value = asDraft ? "draft" : "publish";

  const activityFormValues = activityFormRef.value?.values;
  const workshopFormValues = workshopFormRef.value?.values;
  if (!activityFormValues) {
    saveAction.value = null;
    return;
  }

  const activityValidation = await activityFormRef.value?.validateForm?.();
  if (activityValidation && Object.keys(activityValidation).length > 0) {
    saveAction.value = null;
    return;
  }
  persistActiveDraft();

  const current = await ensureTranslationRecordExists();
  if (!current?.id) {
    saveAction.value = null;
    return;
  }

  const nextTranslationStatus = asDraft ? "draft" : "publish";
  languageStatuses.value[activeLanguage.value] = nextTranslationStatus;

  const workshopData = workshopFormValues?.value || workshopFormValues || {};
  const payload = {
    title: activityFormValues.title || "",
    slug: activityFormValues.slug || "",
    cw_program_id: activityFormValues.cw_program_id || "",
    status: nextTranslationStatus,
    seo_title: seo.value.seo_title || "",
    seo_description: seo.value.seo_description || "",
    is_enabled: !!activityFormValues.is_enabled,
    language: activeLanguage.value,
    activity_icon: activityFormRef.value?.getLogo?.() || "",
    activity_details: {
      tag: activityFormValues.tag || "",
      activity_name: activityFormValues.activity_name || "",
      activity_heading: activityFormValues.activity_heading || "",
      activity_description: activityFormValues.activity_description || "",
      created_for: activityFormValues.created_for || "",
      ideal_for_text: activityFormValues.ideal_for_text || "",
      age: activityFormValues.age || null,
      age_text: activityFormValues.age_text || "",
      grade: activityFormValues.grade || "",
      grade_text: activityFormValues.grade_text || "",
      duration_heading: activityFormValues.duration_heading || "",
      duration: activityFormValues.duration || "",
      duration_text: activityFormValues.duration_text || "",
      image: activityFormValues.image || "",
      cta_button: activityFormValues.cta_button || { text: "", url: "" },
      workshop_details: workshopData,
      feature_section: aiFeatureFormRef.value?.getValues?.() ?? null,
    },
    is_required_for_translation: globalTranslationRequired.value,
  };

  try {
    const updateResponse = await activityStore.updateActivity(
      current.id,
      payload,
    );
    const updatedCurrent =
      updateResponse?.data?.data || updateResponse?.data || current;
    await loadTranslationFamily({
      preferredLanguage: activeLanguage.value,
      currentRecord: updatedCurrent,
    });
  } catch (err) {
    const message =
      err?.response?.data?.message ||
      err?.message ||
      "Failed to save activity. Please review your inputs.";
    error(message);
  } finally {
    saveAction.value = null;
  }
}

function handleCancel() {
  router.push("/activity");
}

const handleGlobalTranslationRequiredUpdate = (value) => {
  globalTranslationRequired.value = !!value;
  Object.keys(activityByLanguage.value).forEach((code) => {
    if (activityByLanguage.value[code]) {
      activityByLanguage.value[code].is_required_for_translation =
        globalTranslationRequired.value;
    }
  });
};

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

const handleMediaSelect = (selectedMedia) => {
  const { fieldKey, multiple, index } = currentImageField.value;

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

  const mediaArray = multiple
    ? Array.isArray(selectedMedia)
      ? selectedMedia
      : [selectedMedia]
    : [selectedMedia];

  const imageUrls = mediaArray.filter((m) => m?.url).map((m) => m.url);

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

  if (fieldKey === "sliderImages") {
    workshopFormRef.value.formData.sliders.sliderImages = imageUrls;
  } else if (fieldKey === "reverseSliderImages") {
    workshopFormRef.value.formData.sliders.reverseSliderImages = imageUrls;
  } else if (fieldKey === "gallery_slide_robot") {
    const slide = workshopFormRef.value.formData.gallery_slides?.[index];
    if (slide) slide.robot_image = imageUrls[0] || "";
  }

  showMediaPicker.value = false;
};

onMounted(async () => {
  if (!setting.value) {
    await settingStore.getSetting();
  }
  await loadTranslationFamily({});
});

onBeforeUnmount(() => {
  stopTranslationProgress();
});

const translationProgressPool = [
  "Analyzing activity sections for high quality translation…",
  "Translating workshop and activity details in sequence…",
  "Applying consistent educational tone for this language…",
  "Finalizing translated activity content…",
];

const startTranslationProgress = () => {
  const pickMessage = () =>
    translationProgressPool[
      Math.floor(Math.random() * translationProgressPool.length)
    ];
  translationProgressMessage.value = pickMessage();
  if (translationMessageTimer) clearInterval(translationMessageTimer);
  translationMessageTimer = setInterval(() => {
    translationProgressMessage.value = pickMessage();
  }, 3200);
};

const stopTranslationProgress = () => {
  if (translationMessageTimer) {
    clearInterval(translationMessageTimer);
    translationMessageTimer = null;
  }
  translationProgressMessage.value = "";
};
</script>

<template>
  <OverlayLoader :loading="busy" />

  <div class="edit-activity-layout">
    <template v-if="activeActivity">
      <div class="page-header">
        <div>
          <h1 class="page-title">Edit Activity</h1>
          <p class="page-subtitle">Update activity details</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">
          <VAlert
            v-if="platformStatusMessage"
            type="warning"
            variant="tonal"
            class="mb-4"
          >
            {{ platformStatusMessage }}
          </VAlert>
          <EntityTranslationToolbar
            class="translation-toolbar-block"
            :model-value="activeLanguage"
            :tabs="translationTabs"
            :disabled="saving || isLoadingUpdatePreview || isLoadingResetPreview"
            :translating="translating"
            :selected-label="selectedLanguageLabel"
            :status-by-language="languageStatuses"
            :can-remove="isSuperAdmin && activeLanguage !== 'en'"
            :can-reset="canResetToGlobal"
            :can-update-to-latest-global="canUpdateToLatestGlobal"
            :is-locally-modified="isLocallyModifiedTranslation"
            @update:model-value="handleLanguageTabChange"
            @translate="handleTranslateActiveLanguage"
            @remove="handleRemoveActiveTranslation"
            @reset-to-global="handleResetToGlobal"
            @update-to-latest-global="handleUpdateToLatestGlobal"
          />
          <div
            v-if="translating && translationProgressMessage"
            class="translation-progress-note"
          >
            <VIcon size="16" color="primary">bx-loader-alt</VIcon>
            <span>{{ translationProgressMessage }}</span>
          </div>
          <Transition name="tab-fade" mode="out-in">
            <div :key="activeLanguage">
              <AccordionExpandToggle :group="activityAccordion" />

              <BasicActivityForm
                ref="activityFormRef"
                :loading="saving || isEnglishReadOnlyForFranchise"
                :lock-global-identity-fields="activeLanguage !== 'en'"
                mode="edit"
                :activity="activeActivity"
                @cancel="handleCancel"
              />

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

              <WorkshopDetailsForm
                ref="workshopFormRef"
                :loading="saving || isEnglishReadOnlyForFranchise"
                mode="edit"
                :workshop-details="
                  activeActivity?.activity_details?.workshop_details
                "
                :slug="activeActivity?.slug || ''"
                @cancel="handleCancel"
                @open-media-picker="handleMediaPickerOpen"
              />

              <AiFeatureForm
                v-if="showAiSection"
                ref="aiFeatureFormRef"
                :loading="saving || isEnglishReadOnlyForFranchise"
                mode="edit"
                :record="activeActivity"
                record-key="activity_details"
                panel-injection-key="activeActivityPanel"
              />

              <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 || isEnglishReadOnlyForFranchise"
                  />
                </AccordionSection>
              </VExpansionPanels>
            </div>
          </Transition>
        </div>

        <div class="side-content">
          <div class="sticky-wrapper">
            <div class="sidebar-card">
              <h3 class="sidebar-title">
                Current status: {{ currentStatusLabel }}
              </h3>
              <p class="sidebar-text">Last updated: {{ lastUpdatedLabel }}</p>

              <PublishDraftActions
                :loading="isSaveInProgress || isEnglishReadOnlyForFranchise"
                :loading-action="saveAction"
                @publish="handleSave(false)"
                @draft="handleSave(true)"
              />

              <div class="preview-section">
                <div v-if="previewUrl" class="preview-url-container">
                  <strong>Preview URL:</strong>

                  <div class="preview-url-wrapper">
                    <a
                      :href="previewUrl"
                      target="_blank"
                      rel="noopener noreferrer"
                      class="preview-link"
                      :title="previewUrl"
                    >
                      <span class="url-text">{{ previewUrl }}</span>
                      <i class="pi pi-external-link external-icon"></i>
                    </a>

                    <VBtn
                      icon
                      size="small"
                      variant="text"
                      class="copy-btn"
                      :disabled="
                        isSaveInProgress || isEnglishReadOnlyForFranchise
                      "
                      @click="copyToClipboard(String(previewUrl || ''))"
                    >
                      <i class="bx bx-copy"></i>
                    </VBtn>
                  </div>
                </div>
              </div>
            </div>
            <TranslationSidebarCard
              v-if="isSuperAdmin"
              v-model="selectedLanguageToAdd"
              :options="availableLanguageOptions"
              :required-value="globalTranslationRequired"
              :show-required-toggle="true"
              :disabled="saving"
              @add-language="handleAddLanguage"
              @update:required-value="handleGlobalTranslationRequiredUpdate"
            />
          </div>
        </div>
      </div>
    </template>

    <MediaPickerModal
      v-model="showMediaPicker"
      :multiple="currentImageField.multiple"
      filter-type="image"
      :media-category="currentImageField.mediaCategory"
      @select="handleMediaSelect"
    />
    <ConfirmationDialog
      v-model:visible="showRemoveTranslationDialog"
      title="Remove Translation"
      :message="`Are you sure you want to remove ${selectedLanguageLabel} translation for this activity? This action cannot be undone.`"
      :item="null"
      :loading="saving"
      @confirm="confirmRemoveActiveTranslation"
      @cancel="showRemoveTranslationDialog = false"
    />
    <UpdatePreviewDialog
      v-model="showUpdatePreviewDialog"
      :loading="saving || isLoadingResetPreview || isLoadingUpdatePreview"
      :title="updatePreviewDialogTitle"
      :description="updatePreviewDialogDescription"
      :warning="updatePreviewWarning"
      :changes="updatePreviewData?.changes || []"
      :source-global-version="updatePreviewData?.source_global_version"
      :latest-global-version="updatePreviewData?.latest_global_version"
      :has-local-changes="
        isUpdatePreviewModeReset ? false : updatePreviewHasLocalChanges
      "
      :show-version-comparison="!isUpdatePreviewModeReset"
      :value-from-label="isUpdatePreviewModeReset ? 'Current' : ''"
      :value-to-label="isUpdatePreviewModeReset ? 'Global' : ''"
      :banner="updatePreviewDialogBanner"
      :accept-text="updatePreviewDialogAcceptText"
      cancel-text="Cancel"
      @confirm="handleUpdatePreviewDialogConfirm"
      @cancel="closeUpdatePreviewDialog"
    />
  </div>
</template>

<style scoped>
.edit-activity-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: minmax(0, 1fr) 360px;
  gap: 32px;
}
.main-content {
  display: flex;
  flex-direction: column;
}
.spacer {
  height: 24px;
}
.translation-progress-note {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: #475569;
  font-size: 13px;
  margin: 8px 0 10px;
}
.side-content {
  height: 100%;
}
.sticky-wrapper {
  position: sticky;
  top: 105px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.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: 0;
  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;
}
.preview-url-container strong {
  display: block;
  margin-bottom: 8px;
  color: rgb(var(--v-theme-on-surface)) !important;
}
.preview-section {
  margin-top: 16px;
}
.preview-url-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
}
.preview-link {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #3b82f6 !important;
  text-decoration: none;
}
.preview-link:hover {
  text-decoration: underline;
}
.url-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #3b82f6 !important;
}
.external-icon {
  font-size: 12px;
}
.copy-btn {
  flex-shrink: 0;
}
.translation-toolbar-block {
  margin-bottom: 20px;
}

.tab-fade-enter-active,
.tab-fade-leave-active {
  transition: all 0.25s ease;
}
.tab-fade-enter-from,
.tab-fade-leave-to {
  opacity: 0;
  transform: translateX(10px);
}

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