<script setup>
import MediaPickerModal from "@/components/MediaPickerModal.vue";
import { usePanel } from "@/composables/useAccordionGroup";
import { useAuthStore } from "@/stores/authStore";
import { useField, useForm } from "vee-validate";
import { computed, onMounted, ref, watch } from "vue";
import * as yup from "yup";

const props = defineProps({
  mode: { type: String, default: "create" },
  activity: { type: Object, default: null },
  loading: Boolean,
  lockGlobalIdentityFields: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(["cancel"]);
const showMediaPicker = ref(false);
const selectedImageData = ref(null);
const useAgeInstead = ref(true);
const authStore = useAuthStore();
const { user: authUser } = storeToRefs(authStore);

const isSuperAdmin = computed(
  () => authUser.value?.data?.role === "super_admin",
);
const isIdentityFieldLocked = computed(
  () => !isSuperAdmin.value || props.lockGlobalIdentityFields,
);
const panel = usePanel("activeActivityPanel", "basic-0");

// Validation schema
const validationSchema = yup.object({
  title: yup
    .string()
    .required("Title is required")
    .min(2)
    .max(100, "Title must be at most 100 characters"),
  activity_name: yup
    .string()
    .required("Activity name is required")
    .max(100, "Activity name must be at most 100 characters"),
  activity_heading: yup
    .string()
    .required("Activity heading is required")
    .max(100, "Activity heading must be at most 100 characters"),
  activity_description: yup
    .string()
    .required("Description is required")
    .max(300, "Description must be at most 300 characters"),
  created_for: yup
    .string()
    .required("Created for is required")
    .max(100, "Created for must be at most 100 characters"),
  ideal_for_text: yup
    .string()
    .nullable()
    .max(60, "Ideal for label must be at most 60 characters"),
  cta_button: yup.object({
    text: yup
      .string()
      .nullable()
      .max(50, "Button text must be at most 50 characters"),
  }),
  tag: yup.string().nullable().max(50, "Tag must be at most 50 characters"),
  age: yup
    .string()
    .nullable()
    .max(50, "Age range must be at most 50 characters"),
  age_text: yup.string().nullable(),
  grade: yup.string().nullable().max(50, "Grade must be at most 50 characters"),
  grade_text: yup.string().nullable(),
  duration_heading: yup
    .string()
    .required("Duration heading is required")
    .max(50, "Duration heading must be at most 50 characters"),
  duration: yup
    .string()
    .nullable()
    .max(20, "Duration must be at most 20 characters"),
  duration_text: yup
    .string()
    .nullable()
    .max(30, "Must be at most 30 characters"),
  slug: yup
    .string()
    .test("slug-required-when-editable", "Slug is required", (value) => {
      if (isIdentityFieldLocked.value) return true;
      return !!String(value || "").trim();
    })
    .matches(
      /^[\w-]+$/,
      "Slug can only contain letters, numbers, hyphen, and underscore",
    )
    .max(100, "Slug must be at most 100 characters"),
  cw_program_id: yup
    .number()
    .transform((value, originalValue) =>
      originalValue === "" ||
      originalValue === null ||
      originalValue === undefined
        ? null
        : Number(originalValue),
    )
    .test(
      "cw-program-id-required-when-editable",
      "CW Program ID is required",
      (value) => {
        if (isIdentityFieldLocked.value) return true;
        return value !== null && value !== undefined && value !== "";
      },
    )
    .typeError("CW Program ID must be a number")
    .integer("CW Program ID must be an integer")
    .min(1, "CW Program ID must be greater than 0"),
  is_enabled: yup.boolean(),
  is_required_for_translation: yup.boolean(),
  activity_icon: yup.string().nullable(),
});

const { errors, validate, resetForm, values, setTouched, validateField } = useForm({
  validationSchema,
  initialValues: {
    title: "",
    activity_name: "",
    activity_heading: "",
    activity_description: "",
    created_for: "",
    ideal_for_text: "Ideal FOR:",
    tag: "",
    age: "",
    age_text: "Age",
    grade: "",
    grade_text: "Grade",
    duration_heading: "Duration",
    duration: "",
    duration_text: "mins",
    slug: "",
    cw_program_id: "",
    image: "",
    cta_button: { text: "", url: "" },
    is_enabled: false,
    is_required_for_translation: false,
    activity_icon: "",
  },
});

// Fields
const { value: title, handleBlur: handleTitleBlur } = useField("title");
const { value: activity_name, handleBlur: handleActivityNameBlur } =
  useField("activity_name");
const { value: activity_heading, handleBlur: handleActivityHeadingBlur } =
  useField("activity_heading");
const { value: activity_description } = useField("activity_description");
const { value: created_for } = useField("created_for");
const { value: ideal_for_text } = useField("ideal_for_text");
const { value: cta_button_text } = useField("cta_button.text");
const { value: tag } = useField("tag");
const { value: slug } = useField("slug");
const { value: cw_program_id } = useField("cw_program_id");
const { value: image, setValue: setImageValue } = useField("image");
const { value: is_enabled } = useField("is_enabled");
const { value: is_required_for_translation } = useField(
  "is_required_for_translation",
);
const { value: activity_icon, setValue: setIconValue } =
  useField("activity_icon");

// Independent Value & Text Fields
const { value: age } = useField("age");
const { value: age_text } = useField("age_text");
const { value: grade } = useField("grade");
const { value: grade_text } = useField("grade_text");
const { value: duration_heading } = useField("duration_heading");
const { value: duration } = useField("duration");
const { value: duration_text } = useField("duration_text");

// Options
const ageTextOptions = [{ title: "Age", value: "Age" }];

const gradeTextOptions = [
  { title: "Grade", value: "Grade" },
  { title: "Class", value: "Class" },
  { title: "Level", value: "Level" },
];

// Real-Time Shaking Logic
const isShaking = ref(false);

const triggerShake = () => {
  isShaking.value = true;
  setTimeout(() => {
    isShaking.value = false;
  }, 400);
};

// Map string keys to refs returned from vee-validate
const formRefs = {
  title,
  activity_name,
  activity_heading,
  activity_description,
  created_for,
  ideal_for_text,
  "cta_button.text": cta_button_text,
  tag,
  age,
  grade,
  duration_heading,
  duration,
  duration_text,
  slug,
  cw_program_id,
  activity_icon,
};

// Generic sanitization
const handleInputValue = (key, val, maxLength, type = "text") => {
  if (typeof val !== "string") return;
  const targetRef = formRefs[key];
  if (!targetRef) return;

  let cleanValue = val;
  if (type === "alphanumeric") {
    cleanValue = cleanValue.replace(/[^a-zA-Z0-9\s.,!?'"\-+]/g, "");
  } else if (type === "numeric") {
    cleanValue = cleanValue.replace(/[^0-9]/g, "");
  } else if (type === "slug") {
    cleanValue = cleanValue.replace(/[^a-zA-Z0-9_-]/g, ""); // allow A-Z, a-z, 0-9, _ and -
  }

  if (maxLength && cleanValue.length > maxLength) {
    cleanValue = cleanValue.slice(0, maxLength);
  }

  const wasModified = cleanValue !== val;
  if (wasModified) triggerShake();

  targetRef.value = cleanValue;

  if (wasModified) {
    setTimeout(() => {
      targetRef.value = cleanValue;
    }, 0);
  }
};

// CW Program ID numeric
const handleCwProgramIdInput = (val) => {
  if (typeof val !== "string" && typeof val !== "number") return;

  let strVal = String(val);
  let cleanValue = strVal.replace(/[^0-9]/g, "");

  if (cleanValue.length > 10) {
    cleanValue = cleanValue.slice(0, 10);
  }

  const wasModified = cleanValue !== strVal;
  if (wasModified) triggerShake();

  cw_program_id.value = cleanValue;

  if (wasModified) {
    setTimeout(() => {
      cw_program_id.value = cleanValue;
    }, 0);
  }
};

/* ---- Per-section "Cancel without saving" ----
 * The details sections snapshot a plain formData object, but the fields here are
 * vee-validate managed, so the snapshot is a clone of `values` taken whenever the
 * form is seeded, and cancel replays it back through resetForm. Declared before
 * the watch below so its immediate run can snapshot safely.
 */
const originalValues = ref(null);
const snapshotOriginal = () => {
  originalValues.value = JSON.parse(JSON.stringify(values));
};

// Create mode never reaches the resetForm watch, so seed from the defaults.
onMounted(() => {
  if (!originalValues.value) snapshotOriginal();
});

const hasSectionChanges = computed(
  () =>
    !!originalValues.value &&
    JSON.stringify(values) !== JSON.stringify(originalValues.value),
);

const cancelSection = () => {
  if (!originalValues.value) return;
  resetForm({ values: JSON.parse(JSON.stringify(originalValues.value)) });
  // Keep the image preview in step with the restored field.
  selectedImageData.value = values.image ? { url: values.image } : null;
};

watch(
  () => props.activity,
  (newActivity) => {
    if (props.mode === "edit" && newActivity) {
      const details = newActivity.activity_details || {};

      resetForm({
        values: {
          title: newActivity.title || "",
          slug: newActivity.slug || "",
          cw_program_id:
            newActivity.cw_program_id !== null &&
            newActivity.cw_program_id !== undefined
              ? String(newActivity.cw_program_id)
              : "",
          is_enabled: !!newActivity.is_enabled,
          activity_name:
            details.activity_name || newActivity.activity_name || "",
          activity_heading:
            details.activity_heading || newActivity.activity_heading || "",
          activity_description:
            details.activity_description ||
            newActivity.activity_description ||
            "",
          created_for: details.created_for ?? newActivity.created_for ?? "",
          ideal_for_text:
            details.ideal_for_text ??
            newActivity.ideal_for_text ??
            "Ideal FOR:",
          tag: details.tag || newActivity.tag || "",

          age: details.age
            ? String(details.age)
            : newActivity.age
              ? String(newActivity.age)
              : "",
          age_text: details.age_text ?? newActivity.age_text ?? "",

          grade: details.grade || newActivity.grade || "",
          grade_text: details.grade_text ?? newActivity.grade_text ?? "",

          duration_heading:
            details.duration_heading ||
            newActivity.duration_heading ||
            "Duration",
          duration: details.duration || newActivity.duration || "",
          duration_text:
            details.duration_text || newActivity.duration_text || "mins",

          image: details.image || newActivity.image || "",
          cta_button: details.cta_button ||
            newActivity.cta_button || { text: "", url: "" },
          is_required_for_translation:
            !!newActivity.is_required_for_translation,
          activity_icon: newActivity.activity_icon || "",
        },
      });

      if (details.image || newActivity.image) {
        selectedImageData.value = { url: details.image || newActivity.image };
      }

      const ageVal = details.age || newActivity.age;
      const gradeVal = details.grade || newActivity.grade;
      if (ageVal) {
        useAgeInstead.value = true;
      } else if (gradeVal) {
        useAgeInstead.value = false;
      }

      snapshotOriginal();
    }
  },
  { immediate: true, deep: true },
);

const handleMediaSelect = (media) => {
  if (media?.url) {
    if (activePickerType.value === "logo") {
      setIconValue(media.url);
    } else {
      setImageValue(media.url);
      selectedImageData.value = media;
    }
  }
  showMediaPicker.value = false;
};

const activePickerType = ref("image");
const openLogoPicker = () => {
  activePickerType.value = "logo";
  showMediaPicker.value = true;
};

const openImagePicker = () => {
  activePickerType.value = "image";
  showMediaPicker.value = true;
};

const removeImage = () => {
  setImageValue("");
  selectedImageData.value = null;
};

const removeLogo = () => {
  setIconValue("");
};

defineExpose({
  values,
  errors,
  validateForm: async () => {
    setTouched({
      title: true,
      activity_name: true,
      activity_heading: true,
      activity_description: true,
      created_for: true,
      ideal_for_text: true,
      "cta_button.text": true,
      tag: true,
      age: true,
      age_text: true,
      grade: true,
      grade_text: true,
      duration_heading: true,
      duration: true,
      duration_text: true,
      slug: true,
      cw_program_id: true,
      image: true,
      activity_icon: true,
      cta_button: true,
      is_enabled: true,
      is_required_for_translation: true,
    });
    return (await validate()).errors;
  },
  getLogo: () => activity_icon.value,
});

const handleFieldBlur = (field) => {
  validateField(field);
};
</script>

<template>
  <div class="activity-form-container">
    <VExpansionPanels
      v-model="panel"
      variant="accordion"
      class="custom-accordion-panels"
      elevation="0"
    >
      <VExpansionPanel class="form-panel-card" elevation="0">
        <VExpansionPanelTitle class="section-header" hide-actions>
          <div class="section-header-content">
            <div class="section-left">
              <div class="section-icon-wrapper">
                <VIcon color="white" size="20">bx-layer</VIcon>
              </div>
              <div class="section-text">
                <h3 class="section-name">Basic Information</h3>
                <div class="subtitle-row">
                  <p class="section-subtitle">Core activity details</p>
                  <span class="badge-count">
                    {{ props.isSuperAdmin ? "15 Fields" : "13 Fields" }}
                  </span>
                </div>
              </div>
            </div>
            <div class="section-right">
              <div class="chevron-wrapper">
                <VIcon size="24" class="custom-chevron">bx-chevron-down</VIcon>
              </div>
            </div>
          </div>
        </VExpansionPanelTitle>

        <VExpansionPanelText>
          <div class="panel-body-content">
            <VRow>
              <VCol cols="12" md="4">
                <VTextField
                  v-model="title"
                  @update:model-value="handleInputValue('title', $event, 100)"
                  label="Title"
                  placeholder="Internal Title"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-captions"
                  :counter="100"
                  :error-messages="errors.title"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleTitleBlur"
                />
              </VCol>

              <VCol cols="12" md="4">
                <VTextField
                  v-model="slug"
                  @update:model-value="
                    handleInputValue('slug', $event, 30, 'slug')
                  "
                  label="Slug"
                  placeholder="auto-generated-slug"
                  variant="outlined"
                  density="comfortable"
                  :counter="30"
                  :error-messages="errors.slug"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('slug')"
                  :readonly="isIdentityFieldLocked"
                  :disabled="isIdentityFieldLocked"
                  :hint="
                    isSuperAdmin
                      ? 'Editable by super admin only'
                      : 'Managed globally by super admin'
                  "
                  persistent-hint
                />
              </VCol>

              <VCol cols="12" md="4">
                <VTextField
                  v-model="cw_program_id"
                  @update:model-value="handleCwProgramIdInput"
                  label="CW Program ID"
                  placeholder="e.g. 22"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-hash"
                  :readonly="isIdentityFieldLocked"
                  :disabled="isIdentityFieldLocked"
                  :error-messages="errors.cw_program_id"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('cw_program_id')"
                />
              </VCol>
            </VRow>

            <!--  <VRow v-if="isSuperAdmin">
              <VCol cols="12">
                <VCheckbox
                  v-model="is_required_for_translation"
                  label="Global translation required"
                  color="primary"
                  density="comfortable"
                  hide-details
                />
              </VCol>
            </VRow> -->

            <VRow>
              <VCol cols="12" md="4">
                <VTextField
                  v-model="tag"
                  @update:model-value="handleInputValue('tag', $event, 50)"
                  label="Tag / Category"
                  placeholder="e.g. CODING"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-purchase-tag"
                  :counter="50"
                  :error-messages="errors.tag"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('tag')"
                />
              </VCol>
              <VCol cols="12" md="4">
                <VTextField
                  v-model="activity_name"
                  @update:model-value="
                    handleInputValue('activity_name', $event, 100)
                  "
                  label="Activity Name"
                  placeholder="Public Name"
                  variant="outlined"
                  density="comfortable"
                  :counter="100"
                  :error-messages="errors.activity_name"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleActivityNameBlur"
                />
              </VCol>
              <VCol cols="12" md="4">
                <VTextField
                  v-model="activity_heading"
                  @update:model-value="
                    handleInputValue('activity_heading', $event, 100)
                  "
                  label="Heading"
                  placeholder="Marketing Heading"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-highlight"
                  :counter="100"
                  :error-messages="errors.activity_heading"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleActivityHeadingBlur"
                />
              </VCol>
            </VRow>

            <VRow>
              <VCol cols="12">
                <VTextarea
                  v-model="activity_description"
                  @update:model-value="
                    handleInputValue('activity_description', $event, 300)
                  "
                  label="Description"
                  placeholder="Detailed description..."
                  variant="outlined"
                  rows="3"
                  auto-grow
                  density="comfortable"
                  :counter="300"
                  :error-messages="errors.activity_description"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('activity_description')"
                />
              </VCol>
            </VRow>

            <div class="subsection-divider"></div>

            <VRow>
              <VCol cols="12" md="4">
                <VTextField
                  v-model="created_for"
                  @update:model-value="
                    handleInputValue('created_for', $event, 100)
                  "
                  label="Created For"
                  placeholder="e.g. Camp"
                  variant="outlined"
                  density="comfortable"
                  :counter="100"
                  :error-messages="errors.created_for"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('created_for')"
                />
              </VCol>

              <VCol cols="12" md="4">
                <VTextField
                  v-model="ideal_for_text"
                  @update:model-value="
                    handleInputValue('ideal_for_text', $event, 60)
                  "
                  label="Ideal For Label"
                  placeholder="e.g. Ideal FOR:"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-label"
                  :counter="60"
                  :error-messages="errors.ideal_for_text"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('ideal_for_text')"
                />
              </VCol>

              <VCol cols="12" md="4">
                <VTextField
                  v-model="cta_button_text"
                  @update:model-value="
                    handleInputValue('cta_button.text', $event, 50)
                  "
                  label="CTA Button Text"
                  placeholder="e.g. BOOK NOW"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-mouse"
                  :counter="50"
                  :error-messages="errors['cta_button.text']"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('cta_button.text')"
                />
              </VCol>

              <VCol cols="12" md="4">
                <VTextField
                  v-model="duration_heading"
                  @update:model-value="
                    handleInputValue('duration_heading', $event, 50)
                  "
                  label="Duration Field Label"
                  placeholder="e.g. Duration"
                  variant="outlined"
                  density="comfortable"
                  prepend-inner-icon="bx-text"
                  :counter="50"
                  :error-messages="errors.duration_heading"
                  :class="{ 'shake-animation': isShaking }"
                  @blur="handleFieldBlur('duration_heading')"
                />
              </VCol>

              <VCol cols="12" md="4">
                <div class="d-flex align-start gap-2">
                  <VTextField
                    v-model="duration"
                    @update:model-value="
                      handleInputValue('duration', $event, 20, 'alphanumeric')
                    "
                    label="Duration Value"
                    placeholder="e.g. 90 or Full-day"
                    variant="outlined"
                    density="comfortable"
                    prepend-inner-icon="bx-timer"
                    :counter="20"
                    :error-messages="errors.duration"
                    :class="{
                      'shake-animation': isShaking,
                      'flex-grow-1': true,
                    }"
                    @blur="handleFieldBlur('duration')"
                    hide-details="auto"
                  />
                  <VTextField
                    v-model="duration_text"
                    @update:model-value="
                      handleInputValue(
                        'duration_text',
                        $event,
                        30,
                        'alphanumeric',
                      )
                    "
                    placeholder="e.g. mins or program over 5 days"
                    variant="outlined"
                    density="comfortable"
                    style="max-width: 180px"
                    hide-details="auto"
                    :counter="30"
                    :error-messages="errors.duration_text"
                    :class="{ 'shake-animation': isShaking }"
                  />
                </div>
              </VCol>

              <VCol cols="12" md="4">
                <div
                  class="custom-toggle-box h-100 d-flex flex-column justify-center"
                >
                  <div class="d-flex align-center justify-space-between">
                    <div>
                      <div class="text-subtitle-2 font-weight-bold">
                        Enabled
                      </div>
                      <div class="text-caption text-medium-emphasis">
                        Toggle activity visibility
                      </div>
                    </div>
                    <VSwitch
                      v-model="is_enabled"
                      color="primary"
                      density="comfortable"
                      hide-details
                      inset
                    />
                  </div>
                </div>
              </VCol>
            </VRow>

            <div class="custom-toggle-box mt-4 mb-4">
              <div class="d-flex align-center justify-space-between mb-2">
                <span
                  class="text-subtitle-2 font-weight-bold text-medium-emphasis"
                  >Target Audience</span
                >
                <div class="d-flex align-center gap-2">
                  <span class="text-caption">Grade</span>
                  <VSwitch
                    v-model="useAgeInstead"
                    color="primary"
                    density="compact"
                    hide-details
                    inset
                  />
                  <span class="text-caption">Age</span>
                </div>
              </div>

              <div v-if="useAgeInstead" class="d-flex align-start gap-2">
                <VTextField
                  v-model="age"
                  @update:model-value="
                    handleInputValue('age', $event, 50, 'alphanumeric')
                  "
                  placeholder="e.g. 6-12 or 6+"
                  variant="outlined"
                  density="comfortable"
                  :counter="50"
                  :error-messages="errors.age"
                  :class="{ 'shake-animation': isShaking, 'flex-grow-1': true }"
                  @blur="handleFieldBlur('age')"
                  hide-details="auto"
                />
                <VTextField
                  v-model="age_text"
                  @update:model-value="
                    handleInputValue('age_text', $event, 20, 'alphanumeric')
                  "
                  placeholder="e.g. Age"
                  variant="outlined"
                  density="comfortable"
                  :counter="20"
                  style="max-width: 120px"
                  hide-details="auto"
                />
              </div>

              <div v-else class="d-flex align-start gap-2">
                <VTextField
                  v-model="grade"
                  @update:model-value="
                    handleInputValue('grade', $event, 50, 'alphanumeric')
                  "
                  placeholder="e.g. 1st-5th"
                  variant="outlined"
                  density="comfortable"
                  :counter="50"
                  :error-messages="errors.grade"
                  :class="{ 'shake-animation': isShaking, 'flex-grow-1': true }"
                  @blur="handleFieldBlur('grade')"
                  hide-details="auto"
                />
                <VTextField
                  v-model="grade_text"
                  @update:model-value="
                    handleInputValue('grade_text', $event, 20, 'alphanumeric')
                  "
                  placeholder="e.g. Grade"
                  variant="outlined"
                  density="comfortable"
                  :counter="20"
                  style="max-width: 120px"
                  hide-details="auto"
                />
              </div>
            </div>

            <VRow class="mt-2">
              <VCol cols="12" md="6">
                <div class="custom-toggle-box">
                  <span
                    class="text-subtitle-2 font-weight-medium text-medium-emphasis mb-3 d-block"
                  >
                    <VIcon size="18" class="me-1">bx-image</VIcon>
                    Activity Image
                  </span>

                  <div v-if="!selectedImageData?.url && !image">
                    <VBtn
                      color="#003b6f"
                      class="text-white text-capitalize w-100"
                      prepend-icon="bx-image-add"
                      variant="flat"
                      height="44"
                      @click="openImagePicker"
                    >
                      Select Image
                    </VBtn>
                  </div>
                  <div v-else class="d-flex flex-column align-center gap-3">
                    <div class="preview-container position-relative">
                      <img
                        :src="selectedImageData?.url || image"
                        class="large-preview-img"
                      />
                      <VBtn
                        icon="bx-x"
                        size="x-small"
                        color="error"
                        variant="elevated"
                        class="remove-img-btn"
                        @click="removeImage"
                      />
                    </div>
                    <VBtn
                      color="#003b6f"
                      class="text-white text-capitalize w-100"
                      prepend-icon="bx-revision"
                      variant="flat"
                      @click="openImagePicker"
                    >
                      Change Image
                    </VBtn>
                  </div>
                </div>
              </VCol>

              <VCol cols="12" md="6">
                <div class="custom-toggle-box">
                  <span
                    class="text-subtitle-2 font-weight-medium text-medium-emphasis mb-3 d-block"
                  >
                    <VIcon size="18" class="me-1">bx-paint-roll</VIcon>
                    Activity Logo (Language Specific)
                  </span>

                  <div v-if="!activity_icon">
                    <VBtn
                      color="#003b6f"
                      class="text-white text-capitalize w-100"
                      prepend-icon="bx-image-add"
                      variant="flat"
                      height="44"
                      @click="openLogoPicker"
                    >
                      Select Logo
                    </VBtn>
                  </div>
                  <div v-else class="d-flex flex-column align-center gap-3">
                    <div class="preview-container position-relative">
                      <img :src="activity_icon" class="large-preview-img" />
                      <VBtn
                        icon="bx-x"
                        size="x-small"
                        color="error"
                        variant="elevated"
                        class="remove-img-btn"
                        @click="removeLogo"
                      />
                    </div>
                    <VBtn
                      color="#003b6f"
                      class="text-white text-capitalize w-100"
                      prepend-icon="bx-revision"
                      variant="flat"
                      @click="openLogoPicker"
                    >
                      Change Logo
                    </VBtn>
                  </div>
                </div>
              </VCol>
            </VRow>

            <!-- Revert this section's unsaved edits (other sections keep theirs) -->
            <div v-if="hasSectionChanges" class="section-cancel-row">
              <VBtn
                variant="text"
                color="error"
                size="small"
                class="section-cancel-btn"
                @click="cancelSection"
              >
                <VIcon size="18" class="me-1">bx-x</VIcon>
                Cancel without saving
              </VBtn>
            </div>
          </div>
        </VExpansionPanelText>
      </VExpansionPanel>
    </VExpansionPanels>

    <MediaPickerModal
      v-model="showMediaPicker"
      :multiple="false"
      filter-type="image"
      :media-category="
        activePickerType === 'logo'
          ? isSuperAdmin
            ? `activitylogo-${slug || 'temp'}-${activity?.language || 'en'}`
            : `activitylogo-${slug || 'temp'}`
          : `activity-${slug || 'temp'}`
      "
      @select="handleMediaSelect"
    />
  </div>
</template>

<style scoped>
/* ========== PER-SECTION CANCEL (matches AccordionSection.vue) ========== */
.section-cancel-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}

.section-cancel-btn {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 600;
}

.shake-animation {
  animation: shake 0.4s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.shake-animation :deep(.v-field) {
  background-color: #fff0f0 !important;
  transition: background-color 0.1s ease;
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}

.form-panel-card {
  border-radius: 8px !important;
  border: 1px solid #e2e8f0;
  background: #ffffff;
  transition: all 0.2s ease;
  overflow: hidden;
  margin-bottom: 0;
}
.form-panel-card::before {
  box-shadow: none !important;
}
.form-panel-card.v-expansion-panel--active {
  border-color: #2196f3;
  box-shadow: 0 4px 12px rgba(33, 150, 243, 0.1) !important;
}

.section-header {
  padding: 8px 16px !important;
  min-height: 56px !important;
  background-color: #fff;
}
.form-panel-card.v-expansion-panel--active .section-header {
  background-color: #f8fbff;
}

.section-header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}
.section-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.section-icon-wrapper {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #003b6f, #00569e);
  box-shadow: 0 4px 10px rgba(0, 59, 111, 0.2);
}

.section-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.section-name {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: #1e293b;
  line-height: 1.2;
}

.subtitle-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}
.section-subtitle {
  margin: 0;
  font-size: 12px;
  color: #64748b;
}
.badge-count {
  font-size: 10px;
  font-weight: 600;
  color: #64748b;
  background: #f1f5f9;
  padding: 1px 6px;
  border-radius: 4px;
  border: 1px solid #e2e8f0;
}

.section-right {
  display: flex;
  align-items: center;
}

.chevron-wrapper {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
}
.form-panel-card.v-expansion-panel--active .chevron-wrapper {
  transform: rotate(180deg);
}
.custom-chevron {
  color: #94a3b8;
}
.form-panel-card.v-expansion-panel--active .custom-chevron {
  color: #2196f3;
}

.panel-body-content {
  padding: 20px 4px 4px;
}
.subsection-divider {
  height: 1px;
  background: #f1f5f9;
  margin: 20px 0;
}

.custom-toggle-box {
  background: #f8fafc;
  border: 1px dashed #cbd5e1;
  padding: 10px;
  border-radius: 12px;
}
.preview-container {
  width: 100%;
  max-width: 90px;
  aspect-ratio: 1;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.large-preview-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 3px;
}
.remove-img-btn {
  position: absolute !important;
  top: 4px !important;
  right: 4px !important;
  width: 20px !important;
  height: 20px !important;
  min-width: 0 !important;
  border-radius: 50% !important;
  z-index: 2;
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
}
.preview-container:hover .remove-img-btn {
  opacity: 1;
}
.remove-img-btn :deep(.v-icon) {
  font-size: 13px !important;
}
</style>
