<template>
  <div class="row q-col-gutter-md">
    <!-- Matrícula -->
    <DefaultCurrencyInput
      v-model="modelValue.registration_value"
      class="col-12"
      label="Valor da Matrícula"
    />

    <ExclusiveCheckboxPair
      class="col-12"
      :included="modelValue.registration_included_in_course"
      :installments="modelValue.registration_installments_allowed"
      @update:included="setExclusive('registration', 'included')"
      @update:installments="setExclusive('registration', 'installments')"
    />

    <template v-if="modelValue.registration_installments_allowed">
      <DefaultInput
        v-model="modelValue.registration_max_installments"
        class="col-6"
        label="Quantidade de Parcelas Máximas"
        min="1"
        type="number"
      />

      <div class="col-6 installment-hint">
        Valor da Parcela: {{ formatInstallment(registrationInstallmentValue) }}
      </div>
    </template>

    <q-separator class="col-12" />

    <!-- Aulas -->
    <DefaultCurrencyInput
      v-model="modelValue.classes_value"
      class="col-12"
      label="Valor de Aulas"
    />

    <ExclusiveCheckboxPair
      class="col-12"
      :included="modelValue.classes_included_in_course"
      :installments="modelValue.classes_installments_allowed"
      @update:included="setExclusive('classes', 'included')"
      @update:installments="setExclusive('classes', 'installments')"
    />

    <template v-if="modelValue.classes_installments_allowed">
      <DefaultInput
        v-model="modelValue.classes_max_installments"
        class="col-4"
        label="Quantidade de Parcelas Máximas"
        min="1"
        type="number"
      />

      <div class="col-4 installment-hint">
        Valor da Parcela: {{ formatInstallment(classesInstallmentValue) }}
      </div>

      <DefaultInput
        v-model="modelValue.classes_discount_percentage"
        class="col-4"
        label="Desconto (%)"
        max="100"
        min="0"
        type="number"
      />
    </template>

    <q-separator class="col-12" />

    <!-- Materiais -->
    <div class="col-12 text-weight-medium">Materiais</div>

    <div
      v-for="(material, index) in modelValue.materials"
      :key="index"
      class="col-12"
    >
      <div class="row q-col-gutter-sm items-center">
        <DefaultSelect
          v-model="material.product_id"
          class="col"
          emit-value
          label="Material"
          map-options
          :options="productOptions"
          @update:model-value="onProductSelected(material)"
        />

        <DefaultInput
          v-model="material.quantity"
          class="col-2"
          label="Qtd"
          min="1"
          type="number"
        />

        <DefaultCurrencyInput
          v-model="material.price"
          class="col-3"
          label="R$ Unitário"
        />

        <div class="col-auto">
          <q-btn
            v-if="index === modelValue.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>

    <ExclusiveCheckboxPair
      class="col-12"
      :included="modelValue.materials_included_in_course"
      :installments="modelValue.materials_installments_allowed"
      @update:included="setExclusive('materials', 'included')"
      @update:installments="setExclusive('materials', 'installments')"
    />

    <template v-if="modelValue.materials_installments_allowed">
      <DefaultInput
        v-model="modelValue.materials_max_installments"
        class="col-6"
        label="Quantidade de Parcelas Máximas"
        min="1"
        type="number"
      />

      <div class="col-6 installment-hint">
        Valor da Parcela: {{ formatInstallment(materialsInstallmentValue) }}
      </div>
    </template>

    <q-separator class="col-12" />

    <!-- Valor Total do Curso -->
    <div class="col-12 text-weight-medium">Valor Total do Curso</div>

    <DefaultCurrencyInput
      v-model="modelValue.total_value"
      class="col-12"
      label="Valor Total do Curso"
    />

    <DefaultInput
      v-model="modelValue.total_max_installments"
      class="col-6"
      label="Quantidade de Parcelas Máximas"
      min="1"
      type="number"
      :rules="[inputRules.required, inputRules.minValue(1)]"
    />

    <div class="col-6 installment-hint">
      Valor da Parcela: {{ formatInstallment(totalInstallmentValue) }}
    </div>

    <!-- Condição (só Irrecusável) -->
    <template v-if="showCondition">
      <q-separator class="col-12" />

      <DefaultInput
        v-model="modelValue.condition"
        autogrow
        class="col-12"
        label="Condição"
        type="textarea"
      />
    </template>
  </div>
</template>

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

import { formatToBRLCurrency } from "src/helpers/utils";
import { useInputRules } from "src/composables/useInputRules";

import ExclusiveCheckboxPair from "./ExclusiveCheckboxPair.vue";
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";

const { inputRules } = useInputRules();

const modelValue = defineModel({ type: Object, required: true });

const props = defineProps({
  productOptions: {
    default: () => [],
    type: Array,
  },
  showCondition: {
    default: false,
    type: Boolean,
  },
});

const materialsTotalValue = computed(() =>
  modelValue.value.materials.reduce(
    (sum, material) =>
      sum + (Number(material.quantity) || 0) * (Number(material.price) || 0),
    0,
  ),
);

const registrationInstallmentValue = computed(() =>
  installmentValue(
    modelValue.value.registration_value,
    modelValue.value.registration_max_installments,
  ),
);

const classesInstallmentValue = computed(() =>
  installmentValue(
    modelValue.value.classes_value,
    modelValue.value.classes_max_installments,
  ),
);

const materialsInstallmentValue = computed(() =>
  installmentValue(
    materialsTotalValue.value,
    modelValue.value.materials_max_installments,
  ),
);

const totalInstallmentValue = computed(() =>
  installmentValue(
    modelValue.value.total_value,
    modelValue.value.total_max_installments,
  ),
);

// Soma sugerida do Valor Total, considerando só as seções marcadas como
// "incluso no valor do curso". O campo continua editável: só reaplicamos a
// sugestão enquanto o usuário não tiver digitado um valor diferente dela.
let lastSuggestedTotal = null;

const suggestedTotal = computed(() => {
  let total = 0;

  if (modelValue.value.registration_included_in_course) {
    total += Number(modelValue.value.registration_value) || 0;
  }

  if (modelValue.value.classes_included_in_course) {
    total += Number(modelValue.value.classes_value) || 0;
  }

  if (modelValue.value.materials_included_in_course) {
    total += materialsTotalValue.value;
  }

  return total;
});

watch(
  suggestedTotal,
  (newTotal) => {
    if (
      modelValue.value.total_value === null ||
      modelValue.value.total_value === lastSuggestedTotal
    ) {
      modelValue.value.total_value = newTotal;
    }

    lastSuggestedTotal = newTotal;
  },
  { immediate: true },
);

const setExclusive = (section, option) => {
  const includedKey = `${section}_included_in_course`;
  const installmentsKey = `${section}_installments_allowed`;

  modelValue.value[includedKey] = option === "included";
  modelValue.value[installmentsKey] = option === "installments";
};

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

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

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

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

const formatInstallment = (value) =>
  value === null ? "—" : formatToBRLCurrency(value);

function installmentValue(value, maxInstallments) {
  if (!value || !maxInstallments || maxInstallments <= 0) return null;

  return Number(value) / Number(maxInstallments);
}
</script>

<style scoped>
.installment-hint {
  display: flex;
  align-items: center;
  color: #757575;
  font-size: 13px;
}
</style>
