<template>
  <div class="servico-cadastro-page q-mr-md">
    <DefaultHeaderPage :title="{ value: $t('parceiro.tab_servicos'), translate: false }" />

    <div v-if="loadingPage" class="flex flex-center q-pa-xl">
      <q-spinner color="violet-normal" size="50px" />
    </div>

    <q-form v-else ref="formRef" @submit="onSubmit">
      <q-card flat class="cadastro-card q-pa-md">

        <div class="row q-col-gutter-md">
          <div class="col-12 col-md-12">
            <div class="row q-col-gutter-sm">
              <DefaultInput
                v-model="idDisplay"
                label="ID"
                readonly
                class="col-3 input-violet"
              />
              <DefaultInput
                v-model="form.name"
                v-model:error="validationErrors.name"
                :rules="[inputRules.required]"
                :label="$t('common.terms.name')"
                class="col-5 input-violet"
              />
            </div>
          </div>
          <div class="row col-12 q-mt-sm">
            <div class="col-12">
              <DefaultInput
                v-model="form.description"
                v-model:error="validationErrors.description"
                :label="$t('common.terms.description')"
                type="textarea"
                :rows="6"
                class="input-violet"
              />
            </div>
          </div>
        </div>
        <div class="row col-12 q-col-gutter-sm q-mt-sm">
          <div class="col-6 row">
            <div class="col-12 q-pb-md">
              <div class="q-pl-xs q-mb-sm field-label">
                {{ $t('parceiro.service_category') }}
              </div>
              <div v-if="loadingCategories" class="q-pa-xs">
                <q-spinner color="violet-normal" size="20px" />
              </div>
              <div v-else class="row q-gutter-xs">
                <div
                  v-for="cat in categoryOptions"
                  :key="cat.value"
                  class="category-chip"
                  :class="{ 'category-chip--active': form.category_id === cat.value }"
                  @click="form.category_id = cat.value"
                >
                  {{ cat.label }}
                </div>
              </div>
            </div>

            <DefaultCurrencyInput
              v-model="form.price"
              :label="`${$t('parceiro.price')} R$`"
              input-class="input-violet-native"
              class="col-12 col-sm-4 input-violet q-pr-sm"
            />
            <DefaultCurrencyInput
              v-model="form.associate_price"
              :label="`${$t('parceiro.associate_price')} R$`"
              input-class="input-violet-native"
              class="col-12 col-sm-4 input-violet q-px-sm"
            />
            <DefaultCurrencyInput
              v-model="form.supplier_price"
              :label="$t('parceiro.supplier_price')"
              input-class="input-violet-native"
              class="col-12 col-sm-4 input-violet q-pl-sm"
            />


            <div class="col-12 row justify-center q-pt-md">
              <q-btn
                unelevated
                class="btn-gradient servico-submit-btn"
                :label="isEdit ? $t('common.actions.save') : 'CADASTRAR'"
                type="submit"
                :loading="loading"
              />
            </div>
          </div>
          <div class="col-6">
            <div class="col-12 col-md-5">
              <div class="text-right text-subtitle2 text-violet-normal q-mb-sm">
                {{ $t('common.terms.media') }}
              </div>
              <div class="media-grid">
                <div class="media-slot media-slot--add" @click="triggerUpload(null)">
                  <div class="media-slot__placeholder" />
                  <div class="media-slot__overlay">
                    <q-btn
                      round
                      dense
                      flat
                      icon="mdi-plus"
                      color="white"
                      size="sm"
                      class="media-slot__btn-add"
                      :loading="uploadingSlotIdx === -1"
                    />
                  </div>
                </div>

                <div
                  v-for="(item, idx) in mediaItems"
                  :key="idx"
                  class="media-slot"
                >
                  <img
                    :src="item.previewUrl || item.url"
                    class="media-slot__img"
                    alt=""
                  />
                  <div class="media-slot__overlay">
                    <q-btn
                      round
                      dense
                      flat
                      icon="mdi-close"
                      color="white"
                      size="xs"
                      class="media-slot__btn-remove"
                      :loading="removingSlotIdx === idx"
                      @click.stop="removeMedia(idx)"
                    />
                  </div>
                </div>
              </div>

              <input
                ref="fileInputRef"
                type="file"
                accept="image/*,video/*"
                class="hidden"
                @change="onFileSelected"
              />
            </div>
          </div>
        </div>
      </q-card>
    </q-form>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, useTemplateRef } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useQuasar } from "quasar";
import { useI18n } from "vue-i18n";
import { useInputRules } from "src/composables/useInputRules";
import { useSubmitHandler } from "src/composables/useSubmitHandler";
import { getCategories } from "src/api/category";
import {
  getPartnerAgreementService,
  createService,
  updateService,
  uploadServiceMedia,
  deleteServiceMedia,
} from "src/api/partnerAgreementService";

import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";

const route  = useRoute();
const router = useRouter();
const $q     = useQuasar();
const { t }  = useI18n();
const { inputRules } = useInputRules();

const partnerId = computed(() => Number(route.params.id));
const serviceId = computed(() => (route.params.serviceId ? Number(route.params.serviceId) : null));
const isEdit    = computed(() => !!serviceId.value);

const loadingPage      = ref(false);
const loadingCategories = ref(true);
const categoryOptions  = ref([]);

const idDisplay = computed(() => (serviceId.value ? String(serviceId.value).padStart(5, "0") : "—"));

const form = ref({
  partner_agreement_id: partnerId.value,
  name:                 "",
  description:          "",
  service_number:       "",
  category_id:          null,
  price:                null,
  associate_price:      null,
  supplier_price:       null,
  requires_scheduling:  false,
});

const mediaItems      = ref([]);
const currentUploadIdx = ref(null); // null = novo item, number = replace item idx
const uploadingSlotIdx = ref(null); // -1 = add slot, idx = replace slot
const removingSlotIdx  = ref(null);
const formRef         = useTemplateRef("formRef");
const fileInputRef    = useTemplateRef("fileInputRef");

const { loading, validationErrors, execute: submitForm } = useSubmitHandler({
  formRef,
  onSuccess: () => goBack(),
});

const loadCategories = async () => {
  loadingCategories.value = true;
  try {
    const cats = await getCategories("service");
    categoryOptions.value = cats.map((c) => ({ label: c.name, value: c.id }));
  } catch { /* silent */ } finally {
    loadingCategories.value = false;
  }
};

const loadService = async () => {
  if (!isEdit.value) return;
  loadingPage.value = true;
  try {
    const svc = await getPartnerAgreementService(serviceId.value);
    form.value.name                = svc.name                ?? "";
    form.value.description         = svc.description         ?? "";
    form.value.service_number      = svc.service_number      ?? "";
    form.value.category_id         = svc.category_id         ?? null;
    form.value.price               = svc.price               ?? null;
    form.value.associate_price     = svc.associate_price     ?? null;
    form.value.supplier_price      = svc.supplier_price      ?? null;
    form.value.requires_scheduling = svc.requires_scheduling ?? false;

    if (Array.isArray(svc.media)) {
      mediaItems.value = svc.media.map((m) => ({ type: "existing", id: m.id, url: m.url }));
    }
  } catch {
    $q.notify({ type: "negative", message: t("http.errors.failed") });
  } finally {
    loadingPage.value = false;
  }
};

const triggerUpload = (idx) => {
  currentUploadIdx.value = idx;
  uploadingSlotIdx.value = idx === null ? -1 : idx;
  if (fileInputRef.value) {
    fileInputRef.value.value = "";
    fileInputRef.value.click();
  }
  uploadingSlotIdx.value = null;
};

const onFileSelected = async (e) => {
  const file = e.target.files?.[0];
  if (!file) return;

  const idx        = currentUploadIdx.value; // null = novo, number = substituir
  const isNew      = idx === null;
  const previewUrl = URL.createObjectURL(file);

  if (isEdit.value) {
    const existingItem = !isNew ? mediaItems.value[idx] : null;

    if (existingItem?.type === "existing") {
      removingSlotIdx.value = idx;
      try {
        await deleteServiceMedia(serviceId.value, existingItem.id);
      } catch {
        $q.notify({ type: "negative", message: t("http.errors.failed") });
        removingSlotIdx.value = null;
        URL.revokeObjectURL(previewUrl);
        return;
      }
      removingSlotIdx.value = null;
    }

    uploadingSlotIdx.value = isNew ? -1 : idx;
    try {
      const newMedia = await uploadServiceMedia(serviceId.value, file);
      const newItem  = { type: "existing", id: newMedia.id, url: newMedia.url };
      if (isNew) {
        mediaItems.value.push(newItem);
      } else {
        mediaItems.value[idx] = newItem;
      }
    } catch {
      $q.notify({ type: "negative", message: t("http.errors.failed") });
    } finally {
      uploadingSlotIdx.value = null;
      URL.revokeObjectURL(previewUrl);
    }
  } else {
    const pendingItem = { type: "pending", file, previewUrl };
    if (isNew) {
      mediaItems.value.push(pendingItem);
    } else {
      const old = mediaItems.value[idx];
      if (old?.previewUrl) URL.revokeObjectURL(old.previewUrl);
      mediaItems.value[idx] = pendingItem;
    }
  }
};

const removeMedia = async (idx) => {
  const item = mediaItems.value[idx];
  if (!item) return;

  if (item.type === "existing") {
    removingSlotIdx.value = idx;
    try {
      await deleteServiceMedia(serviceId.value, item.id);
    } catch {
      $q.notify({ type: "negative", message: t("http.errors.failed") });
      removingSlotIdx.value = null;
      return;
    }
    removingSlotIdx.value = null;
  }

  if (item.previewUrl) URL.revokeObjectURL(item.previewUrl);
  mediaItems.value.splice(idx, 1);
};

const onSubmit = async () => {
  await submitForm(async () => {
    if (isEdit.value) {
      await updateService(serviceId.value, { ...form.value });
    } else {
      const created = await createService({ ...form.value });
      const pending = mediaItems.value.filter((m) => m?.type === "pending");
      await Promise.all(
        pending.map((item) => uploadServiceMedia(created.id, item.file)),
      );
      pending.forEach((item) => {
        if (item.previewUrl) URL.revokeObjectURL(item.previewUrl);
      });
    }
  });
};

const goBack = () => {
  if (route.name === "ParceiroDadosServicoPage") {
    router.push({ name: "MeusDadosPage", query: { tab: "servicos" } });
  } else {
    router.push({
      name:   "ParceiroCadastroPage",
      params: { id: partnerId.value },
      query:  { tab: "servicos" },
    });
  }
};

onMounted(() => {
  loadCategories();
  loadService();
});
</script>

<style lang="scss" scoped>
@use "src/css/quasar.variables.scss" as vars;

.servico-cadastro-page {
  .cadastro-card {
    background: #fff;
    border-radius: 8px;
  }

  .field-label {
    font-size: 0.8rem;
    color: vars.$violet-dark;
  }

  .input-violet {
    :deep(.q-field__control) {
      background: vars.$violet-light !important;
      border-radius: 8px;
    }

    :deep(.q-field__native),
    :deep(.q-field__input),
    :deep(input.input-violet-native) {
      color: vars.$violet-dark !important;
    }

    :deep(.q-field__label) {
      color: vars.$violet-normal !important;
    }

    :deep(.q-field--outlined .q-field__control:before) {
      border-color: transparent !important;
    }

    :deep(.q-field--outlined .q-field__control:after) {
      border-color: vars.$violet-normal !important;
    }
  }

  .category-chip {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 20px;
    font-size: 0.75rem;
    cursor: pointer;
    background: vars.$violet-light;
    color: vars.$violet-dark;
    border: 1px solid transparent;
    transition: background 0.2s, color 0.2s;
    user-select: none;

    &:hover {
      filter: brightness(0.95);
    }

    &--active {
      background: vars.$violet-normal;
      color: #fff;
      border-color: vars.$violet-normal;
    }
  }

  .scheduling-select {
    display: inline-flex;
    align-items: center;
    border: 1px solid #d0c4e8;
    border-radius: 8px;
    padding: 6px 16px;
    background: vars.$violet-light;
    color: vars.$violet-dark;
    font-size: 0.85rem;
    gap: 4px;

    .scheduling-option {
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 4px;
      transition: background 0.15s, color 0.15s;
      user-select: none;

      &--active {
        background: vars.$violet-normal;
        color: #fff;
        font-weight: 600;
      }
    }

    .scheduling-divider {
      color: #aaa;
    }
  }

  .media-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: flex-end;
  }

  .media-slot {
    position: relative;
    width: 145px;
    height: 145px;
    border-radius: 8px;
    overflow: hidden;
    background: vars.$violet-light;
    flex-shrink: 0;
    cursor: pointer;

    &__img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }

    &__placeholder {
      width: 100%;
      height: 100%;
      background: linear-gradient(135deg, #d0b8e8 0%, #b89cd6 100%);
    }

    &__overlay {
      position: absolute;
      inset: 0;
      display: flex;
      align-items: flex-end;
      justify-content: flex-end;
      padding: 6px;
      background: rgba(0, 0, 0, 0.08);
      gap: 4px;
    }

    &__btn-remove {
      position: absolute;
      top: 4px;
      right: 4px;
      background: rgba(0, 0, 0, 0.45) !important;

      :deep(.q-icon) {
        font-size: 14px;
      }
    }

    &__btn-add {
      background: vars.$violet-normal !important;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);

      :deep(.q-icon) {
        font-size: 18px;
      }
    }
  }

  .btn-gradient {
    background: linear-gradient(90deg, #4d1658 0%, #8b30a5 100%) !important;
    color: white !important;
    border-radius: 8px !important;
    padding: 8px 16px;
  }

  .servico-submit-btn {
    min-width: 220px;
    text-transform: uppercase;
    letter-spacing: 1px;
  }
}
</style>
