<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <div style="width: 100%; max-width: 700px">
      <q-card class="overflow-hidden" style="width: 100%">
        <DefaultDialogHeader
          :title="props.package ? 'Editar Proposta Comercial' : 'Nova Proposta Comercial'"
          @close="onDialogCancel"
        />

        <DefaultForm ref="formRef" @submit="onOKClick">
          <q-scroll-area ref="scrollAreaRef" class="form-dialog-scroll-area">
            <q-card-section class="row q-col-gutter-md q-pt-none">
              <CustomTabComponent
                v-model:active-tab="currentTab"
                class="col-12 q-mb-md"
                :tabs="tabs"
              />

              <div
                v-show="currentTab === 'dados'"
                class="col-12"
              >
                <div class="row q-col-gutter-md">
                  <DefaultInput
                    v-model="form.name"
                    v-model:error="validationErrors.name"
                    class="col-12"
                    label="Nome do Pacote"
                    :error-message="validationErrors.name"
                    :rules="[inputRules.required, inputRules.max(255)]"
                  />

                  <DefaultInput
                    v-model="form.quantity_classes"
                    v-model:error="validationErrors.quantity_classes"
                    class="col-12"
                    label="Quantidade de Aulas"
                    min="1"
                    type="number"
                    :error-message="validationErrors.quantity_classes"
                    :rules="[
                      inputRules.requiredNumber,
                      inputRules.integer,
                      inputRules.minValue(1),
                    ]"
                  />

                  <DefaultInput
                    v-model="form.class_duration_hours"
                    v-model:error="validationErrors.class_duration_minutes"
                    class="col-12"
                    label="Duração da Aula (horas)"
                    max="24"
                    step="0.5"
                    type="number"
                    :error-message="validationErrors.class_duration_minutes"
                    :min="0.5"
                    :rules="[
                      inputRules.requiredNumber,
                      inputRules.durationHours,
                    ]"
                  />

                  <div class="col-12 package-duration-hint">
                    A duração padrão das aulas é de 2 horas e pode ser alterada
                    se necessário. É possível configurar no máximo dois dias.
                  </div>

                  <DefaultCurrencyInput
                    v-model="form.contract_register_value"
                    v-model:error="validationErrors.contract_register_value"
                    class="col-4"
                    label="R$ Matrícula"
                    :error-message="validationErrors.contract_register_value"
                  />

                  <DefaultCurrencyInput
                    v-model="form.contract_value"
                    v-model:error="validationErrors.contract_value"
                    class="col-4"
                    label="R$ Total do Contrato"
                    :error-message="validationErrors.contract_value"
                  />

                  <DefaultInput
                    v-model="form.contrat_discount_value"
                    v-model:error="validationErrors.contrat_discount_value"
                    class="col-4"
                    label="Desconto em %"
                    min="0"
                    type="number"
                    :error-message="validationErrors.contrat_discount_value"
                    :rules="[inputRules.minValue(0)]"
                  />

                  <div
                    v-for="(material, index) in form.materials"
                    :key="index"
                    class="col-12"
                  >
                    <div class="row q-col-gutter-sm items-center">
                      <DefaultSelect
                        v-model="material.product_id"
                        v-model:error="
                          validationErrors[`materials.${index}.product_id`]
                        "
                        class="col"
                        emit-value
                        label="Material"
                        map-options
                        :error-message="
                          validationErrors[`materials.${index}.product_id`]
                        "
                        :options="productOptions"
                        :rules="[
                          inputRules.whenValue(
                            () => material.price,
                            inputRules.required,
                          ),
                        ]"
                        @update:model-value="onProductSelected(material)"
                      />

                      <DefaultInput
                        v-model="material.quantity"
                        v-model:error="
                          validationErrors[`materials.${index}.quantity`]
                        "
                        class="col-2"
                        label="Qtd"
                        min="1"
                        type="number"
                        :error-message="
                          validationErrors[`materials.${index}.quantity`]
                        "
                        :rules="[
                          inputRules.whenValue(
                            () => material.product_id,
                            inputRules.requiredNumber,
                          ),
                          inputRules.whenValue(
                            () => material.product_id,
                            inputRules.integer,
                          ),
                          inputRules.whenValue(
                            () => material.product_id,
                            inputRules.minValue(1),
                          ),
                        ]"
                      />

                      <DefaultCurrencyInput
                        v-model="material.price"
                        v-model:error="
                          validationErrors[`materials.${index}.price`]
                        "
                        class="col-3"
                        label="R$ Unitário"
                        :error-message="
                          validationErrors[`materials.${index}.price`]
                        "
                        :rules="[
                          inputRules.whenValue(
                            () => material.product_id,
                            inputRules.requiredNumber,
                          ),
                        ]"
                      />

                      <div class="col-auto">
                        <q-btn
                          v-if="index === form.materials.length - 1"
                          color="primary"
                          icon="mdi-plus"
                          style="border-radius: 8px; height: 40px; width: 40px"
                          unelevated
                          @click="addMaterial"
                        />

                        <q-btn
                          v-else
                          color="negative"
                          dense
                          flat
                          icon="mdi-delete-outline"
                          round
                          @click="removeMaterial(index)"
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <div
                v-show="currentTab === 'pavao'"
                class="col-12"
              >
                <ProposalPricingTab
                  v-model="form.pavao"
                  :product-options="productOptions"
                />
              </div>

              <div
                v-show="currentTab === 'irrecusavel'"
                class="col-12"
              >
                <ProposalPricingTab
                  v-model="form.irrecusavel"
                  :product-options="productOptions"
                  show-condition
                />
              </div>
            </q-card-section>
          </q-scroll-area>

          <q-separator />

          <q-card-actions align="right" class="q-pa-md q-gutter-sm">
            <q-btn
              color="negative"
              label="Cancelar"
              no-caps
              outline
              @click="onDialogCancel"
            />

            <q-btn
              color="primary"
              label="Salvar"
              no-caps
              type="submit"
              unelevated
              :loading="loading"
            />
          </q-card-actions>
        </DefaultForm>
      </q-card>
    </div>
  </q-dialog>
</template>

<script setup>
import { onMounted, computed, ref } from "vue";

import {
  createPackage,
  getPackage,
  updatePackage,
} from "src/api/package";

import { getProductsForSelect } from "src/api/product";
import { useDialogPluginComponent } from "quasar";
import { useForm } from "src/composables/useForm";
import { useInputRules } from "src/composables/useInputRules";
import { useScroll } from "src/composables/useScroll";
import { useSubmitHandler } from "src/composables/useSubmitHandler";

import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultForm from "src/components/defaults/DefaultForm.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import ProposalPricingTab from "./ProposalPricingTab.vue";

defineEmits([...useDialogPluginComponent.emits]);

const props = defineProps({
  package: {
    default: null,
    type: Object,
  },
});

const { dialogRef, onDialogCancel, onDialogHide, onDialogOK } =
  useDialogPluginComponent();

const { inputRules } = useInputRules();

const { scrollToComponent } = useScroll();

const formRef = ref(null);
const scrollAreaRef = ref(null);

const defaultPricingBlock = (withCondition = false) => ({
  classes_discount_percentage: null,
  classes_included_in_course: false,
  classes_installments_allowed: false,
  classes_max_installments: 13,
  classes_value: null,

  materials: [{ price: null, product_id: null, quantity: 1 }],
  materials_included_in_course: false,
  materials_installments_allowed: false,
  materials_max_installments: 13,

  registration_included_in_course: false,
  registration_installments_allowed: false,
  registration_max_installments: 13,
  registration_value: null,

  total_max_installments: 13,
  total_value: null,

  ...(withCondition ? { condition: null } : {}),
});

const { form, getUpdatedFields, setUpdateFormAsOriginal } = useForm(
  {
    class_duration_hours: (props.package?.class_duration_minutes ?? 120) / 60,
    contract_register_value: props.package?.contract_register_value ?? null,
    contract_value: props.package?.contract_value ?? null,
    contrat_discount_value: props.package?.contrat_discount_value ?? null,
    irrecusavel: defaultPricingBlock(true),
    materials: [
      {
        price: null,
        product_id: null,
        quantity: 1,
      },
    ],
    name: props.package?.name ?? null,
    pavao: defaultPricingBlock(),
    quantity_classes: props.package?.quantity_classes ?? null,
  },
  { containerRef: scrollAreaRef },
);

const {
  loading,
  validationErrors,
  execute,
} = useSubmitHandler({
  containerRef: scrollAreaRef,
  formRef,
  onSuccess: (result) => onDialogOK(result),
  scrollFn: scrollToComponent,
});

const currentTab = ref("dados");
const products = ref([]);

const productOptions = computed(() =>
  products.value.map((product) => ({
    label: product.name,
    price_sale: product.price_sale,
    value: product.id,
  })),
);

const tabs = [
  { label: "Dados", name: "dados" },
  { label: "Pavão", name: "pavao" },
  { label: "Irrecusável", name: "irrecusavel" },
];

const addMaterial = () => {
  form.materials.push({
    price: null,
    product_id: null,
    quantity: 1,
  });
};

const onProductSelected = (material) => {
  const option = productOptions.value.find(
    (item) => item.value === material.product_id,
  );

  if (option) {
    material.price = option.price_sale;
  }
};

const removeMaterial = (index) => {
  form.materials.splice(index, 1);
};

const mapPricingBlockFromApi = (data, existingMaterials) => ({
  classes_discount_percentage: data.classes_discount_percentage,
  classes_included_in_course: data.classes_included_in_course,
  classes_installments_allowed: data.classes_installments_allowed,
  classes_max_installments: data.classes_max_installments,
  classes_value: data.classes_value,

  materials: data.materials?.length
    ? data.materials.map((material) => ({
        price: material.price,
        product_id: material.product_id,
        quantity: material.quantity,
      }))
    : existingMaterials,
  materials_included_in_course: data.materials_included_in_course,
  materials_installments_allowed: data.materials_installments_allowed,
  materials_max_installments: data.materials_max_installments,

  registration_included_in_course: data.registration_included_in_course,
  registration_installments_allowed: data.registration_installments_allowed,
  registration_max_installments: data.registration_max_installments,
  registration_value: data.registration_value,

  total_max_installments: data.total_max_installments,
  total_value: data.total_value,

  ...(data.condition !== undefined ? { condition: data.condition } : {}),
});

const numOrNull = (value) =>
  value === null || value === "" || value === undefined ? null : Number(value);

const toPricingPayload = (block, { withCondition = false } = {}) => {
  const payload = {
    classes_discount_percentage: numOrNull(block.classes_discount_percentage),
    classes_included_in_course: block.classes_included_in_course,
    classes_installments_allowed: block.classes_installments_allowed,
    classes_max_installments: Number(block.classes_max_installments) || 13,
    classes_value: numOrNull(block.classes_value),

    materials: block.materials
      .filter((material) => material.product_id)
      .map((material) => ({
        price: Number(material.price),
        product_id: material.product_id,
        quantity: Number(material.quantity),
      })),
    materials_included_in_course: block.materials_included_in_course,
    materials_installments_allowed: block.materials_installments_allowed,
    materials_max_installments: Number(block.materials_max_installments) || 13,

    registration_included_in_course: block.registration_included_in_course,
    registration_installments_allowed: block.registration_installments_allowed,
    registration_max_installments: Number(block.registration_max_installments) || 13,
    registration_value: numOrNull(block.registration_value),

    total_max_installments: Number(block.total_max_installments) || 13,
    total_value: numOrNull(block.total_value),
  };

  if (withCondition) {
    payload.condition = block.condition ?? null;
  }

  return payload;
};

const loadData = async () => {
  products.value = await getProductsForSelect();

  if (props.package?.id) {
    const packageData = await getPackage(props.package.id);

    if (packageData.materials?.length) {
      form.materials = packageData.materials.map((material) => ({
        price: material.price,
        product_id: material.product_id,
        quantity: material.quantity,
      }));
    }

    if (packageData.pavao) {
      form.pavao = mapPricingBlockFromApi(packageData.pavao, form.pavao.materials);
    }

    if (packageData.irrecusavel) {
      form.irrecusavel = mapPricingBlockFromApi(packageData.irrecusavel, form.irrecusavel.materials);
    }
  }

  setUpdateFormAsOriginal();
};

const onOKClick = async () => {
  const validMaterials = form.materials.filter(
    (material) => material.product_id,
  );

  const payload = {
    class_duration_minutes: Math.round(
      Number(form.class_duration_hours) * 60,
    ),

    contract_register_value: form.contract_register_value,
    contract_value: form.contract_value,
    contrat_discount_value: form.contrat_discount_value,

    irrecusavel: toPricingPayload(form.irrecusavel, { withCondition: true }),

    materials: validMaterials.map((material) => ({
      price: Number(material.price),
      product_id: material.product_id,
      quantity: Number(material.quantity),
    })),

    name: form.name,
    pavao: toPricingPayload(form.pavao),
    quantity_classes: form.quantity_classes,
  };

  await execute(() => {
    if (props.package?.id) {
      const updated = {
        ...getUpdatedFields.value,
      };

      if (updated.class_duration_hours !== undefined) {
        updated.class_duration_minutes = payload.class_duration_minutes;

        delete updated.class_duration_hours;
      }

      // Pavão/Irrecusável têm validação cruzada entre campos (par exclusivo
      // de checkbox) que não é seguro fatiar num diff parcial — vão inteiros.
      updated.pavao = payload.pavao;
      updated.irrecusavel = payload.irrecusavel;

      return updatePackage(props.package.id, updated);
    }

    return createPackage(payload);
  });
};

onMounted(loadData);
</script>

<style scoped>
.package-duration-hint {
  color: #757575;
  font-size: 12px;
  line-height: 1.35;
  padding-top: 4px;
  padding-bottom: 2px;
}
</style>
