<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 Pacote' : 'Novo Pacote'"
          @close="onDialogCancel"
        />

        <q-form ref="formRef" @submit="onOKClick">
          <q-card-section class="q-pt-sm">
            <CustomTabComponent
              v-model:active-tab="currentTab"
              :tabs="tabs"
              class="q-mb-md"
            />

            <!-- Tab: Informações -->
            <div v-show="currentTab === 'informacoes'">
              <div class="row q-col-gutter-sm">
                <DefaultInput
                  v-model="form.name"
                  label="Nome do Pacote"
                  class="col-12"
                />

                <DefaultInput
                  v-model="form.quantity_classes"
                  label="Quantidade de Aulas"
                  class="col-12"
                  type="number"
                  min="0"
                />

                <DefaultInput
                  v-model="form.class_duration_hours"
                  label="Duração da Aula (horas)"
                  class="col-12"
                  type="number"
                  min="0.5"
                  max="24"
                  step="0.5"
                />

                <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>

                <DefaultSelect
                  v-model="form.weekday"
                  label="1º Dia da Semana"
                  class="col-4"
                  :options="weekdays"
                  option-value="value"
                  option-label="label"
                  emit-value
                  map-options
                  clearable
                />

                <DefaultInput
                  v-model="form.start_time"
                  label="Horário Inicial"
                  class="col-4"
                  mask="##:##"
                />

                <DefaultInput
                  :model-value="firstEndTime"
                  label="Horário Final"
                  class="col-4"
                  disable
                />

                <DefaultSelect
                  v-model="form.second_weekday"
                  label="2º Dia da Semana"
                  class="col-4"
                  :options="secondWeekdayOptions"
                  option-value="value"
                  option-label="label"
                  emit-value
                  map-options
                  clearable
                />

                <DefaultInput
                  v-model="form.second_start_time"
                  label="Horário Inicial do 2º dia"
                  class="col-4"
                  mask="##:##"
                />

                <DefaultInput
                  :model-value="secondEndTime"
                  label="Horário Final do 2º dia"
                  class="col-4"
                  disable
                />

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

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

                <DefaultInput
                  v-model="form.contrat_discount_value"
                  label="Desconto em %"
                  class="col-4"
                  type="number"
                  min="0"
                  max="100"
                />

                <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"
                      label="Material"
                      class="col"
                      :options="productOptions"
                      emit-value
                      map-options
                      @update:model-value="onProductSelected(material)"
                    />

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

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

                    <div class="col-auto">
                      <q-btn
                        v-if="index === form.materials.length - 1"
                        color="primary"
                        icon="mdi-plus"
                        unelevated
                        style="border-radius: 8px; height: 40px; width: 40px"
                        @click="addMaterial"
                      />
                      <q-btn
                        v-else
                        flat
                        round
                        dense
                        icon="mdi-delete-outline"
                        color="negative"
                        @click="removeMaterial(index)"
                      />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Tab: Unidades -->
            <div v-show="currentTab === 'unidades'">
              <div class="column q-gutter-y-sm">
                <!-- Visível para todas as Unidades -->
                <q-input
                  outlined
                  readonly
                  dense
                  label="Visível para todas as Unidades / Grupos"
                  label-color="secondary"
                  color="secondary"
                  bg-color="white"
                  style="border-radius: 8px"
                >
                  <template #append>
                    <q-btn
                      flat
                      round
                      dense
                      size="sm"
                      icon="mdi-check"
                      color="positive"
                      @click="setAllVisible(true)"
                    />
                    <q-btn
                      flat
                      round
                      dense
                      size="sm"
                      icon="mdi-close-circle-outline"
                      color="negative"
                      @click="setAllVisible(false)"
                    />
                  </template>
                </q-input>

                <!-- Buscar -->
                <div class="row items-center q-gutter-x-sm">
                  <q-input
                    v-model="unitSearch"
                    outlined
                    dense
                    label="Buscar Unidade / Grupo"
                    label-color="secondary"
                    color="secondary"
                    bg-color="white"
                    class="col"
                    style="border-radius: 8px"
                  >
                    <template #append>
                      <q-icon name="mdi-magnify" color="secondary" />
                    </template>
                  </q-input>

                  <q-btn
                    color="primary"
                    icon="mdi-plus"
                    unelevated
                    style="
                      border-radius: 8px;
                      height: 40px;
                      width: 40px;
                      flex-shrink: 0;
                    "
                  />
                </div>

                <!-- Lista de Unidades -->
                <div
                  class="rounded-borders q-pa-sm"
                  style="
                    background-color: #f5f5f5;
                    max-height: 280px;
                    overflow-y: auto;
                  "
                >
                  <div v-if="loadingUnits" class="flex flex-center q-py-md">
                    <q-spinner color="secondary" size="sm" />
                  </div>

                  <template v-else>
                    <div class="row items-center q-mb-xs q-px-sm">
                      <q-icon
                        name="mdi-account-multiple"
                        color="secondary"
                        size="sm"
                        class="q-mr-xs"
                      />
                      <span class="text-body2">
                        Unidades Ativas ({{ filteredUnits.length }})
                      </span>
                    </div>

                    <q-separator class="q-mb-xs" />

                    <div class="row q-px-sm q-py-xs">
                      <span class="col text-caption text-grey-6">Unidade</span>
                      <span class="col-auto text-caption text-grey-6"
                        >Status</span
                      >
                    </div>

                    <template v-for="unit in filteredUnits" :key="unit.id">
                      <q-separator />
                      <div class="row items-center q-px-sm q-py-sm">
                        <span class="col text-body2 row items-center q-gutter-x-xs">
                          {{ formatUnitName(unit) }}
                          <q-icon
                            v-if="lockedUnitIds.has(unit.id)"
                            name="mdi-lock"
                            color="amber-7"
                            size="xs"
                          >
                            <q-tooltip>Visibilidade definida por grupo</q-tooltip>
                          </q-icon>
                        </span>
                        <div class="col-auto row q-gutter-x-xs">
                          <q-btn
                            round
                            unelevated
                            :color="unit.visible ? 'positive' : 'grey-4'"
                            icon="mdi-check"
                            size="xs"
                            @click="unit.visible = true"
                          />
                          <q-btn
                            round
                            :outline="unit.visible"
                            :unelevated="!unit.visible"
                            color="negative"
                            icon="mdi-close"
                            size="xs"
                            :disable="lockedUnitIds.has(unit.id)"
                            @click="!lockedUnitIds.has(unit.id) && (unit.visible = false)"
                          />
                        </div>
                      </div>
                    </template>
                  </template>
                </div>
              </div>
            </div>

            <!-- Tab: Grupos -->
            <div v-show="currentTab === 'grupos'">
              <div class="column q-gutter-y-sm">
                <!-- Visível para todos os Grupos -->
                <q-input
                  outlined
                  readonly
                  dense
                  label="Visível Para todos os Grupos"
                  label-color="secondary"
                  color="secondary"
                  bg-color="white"
                  style="border-radius: 8px"
                >
                  <template #append>
                    <q-btn
                      flat
                      round
                      dense
                      size="sm"
                      icon="mdi-check"
                      color="positive"
                      @click="setAllGroupsVisible(true)"
                    />
                    <q-btn
                      flat
                      round
                      dense
                      size="sm"
                      icon="mdi-close-circle-outline"
                      color="negative"
                      @click="setAllGroupsVisible(false)"
                    />
                  </template>
                </q-input>

                <!-- Buscar Grupo -->
                <q-input
                  v-model="groupSearch"
                  outlined
                  dense
                  label="Buscar Grupo"
                  label-color="secondary"
                  color="secondary"
                  bg-color="white"
                  style="border-radius: 8px"
                >
                  <template #append>
                    <q-icon name="mdi-magnify" color="secondary" />
                  </template>
                </q-input>

                <!-- Lista de Grupos -->
                <div
                  class="rounded-borders q-pa-sm"
                  style="
                    background-color: #f5f5f5;
                    max-height: 280px;
                    overflow-y: auto;
                  "
                >
                  <div v-if="loadingGroups" class="flex flex-center q-py-md">
                    <q-spinner color="secondary" size="sm" />
                  </div>

                  <template v-else>
                    <div class="row items-center q-mb-xs q-px-sm">
                      <q-icon
                        name="mdi-account-group"
                        color="secondary"
                        size="sm"
                        class="q-mr-xs"
                      />
                      <span class="text-body2">
                        Grupos ({{ filteredGroups.length }})
                      </span>
                    </div>

                    <q-separator class="q-mb-xs" />

                    <div class="row q-px-sm q-py-xs">
                      <span class="col text-caption text-grey-6">Grupo</span>
                      <span class="col-6 text-caption text-grey-6">Unidades</span>
                      <span class="col-auto text-caption text-grey-6">Status</span>
                    </div>

                    <template v-for="group in filteredGroups" :key="group.id">
                      <q-separator />
                      <div class="row items-center q-px-sm q-py-sm">
                        <span class="col text-body2">{{ group.name }}</span>
                        <span class="col-6 text-caption text-grey-6">
                          {{ group.unit_ids?.length ?? 0 }} unidade(s)
                        </span>
                        <div class="col-auto row q-gutter-x-xs">
                          <q-btn
                            round
                            unelevated
                            :color="group.visible ? 'positive' : 'grey-4'"
                            icon="mdi-check"
                            size="xs"
                            @click="group.visible = true"
                          />
                          <q-btn
                            round
                            :outline="group.visible"
                            :unelevated="!group.visible"
                            color="negative"
                            icon="mdi-close"
                            size="xs"
                            @click="group.visible = false"
                          />
                        </div>
                      </div>
                    </template>
                  </template>
                </div>
              </div>
            </div>
          </q-card-section>

          <q-card-actions align="right" class="q-px-md q-pb-md">
            <q-btn
              outline
              color="primary"
              label="Cancelar"
              @click="onDialogCancel"
            />
            <q-btn
              color="primary"
              label="Salvar"
              type="submit"
              :loading="loading"
            />
          </q-card-actions>
        </q-form>
      </q-card>
    </div>
  </q-dialog>
</template>

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

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

import { getUnitsForSelect } from "src/api/unit";
import { getPackage, createPackage, updatePackage } from "src/api/package";
import { getProductsForSelect } from "src/api/product";
import { getGroupsForSelect } from "src/api/group";
import { formatUnitName } from "src/helpers/utils";

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

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

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

const formRef = ref(null);
const loading = ref(false);
const loadingUnits = ref(false);
const loadingGroups = ref(false);
const currentTab = ref("informacoes");

const tabs = [
  { name: "informacoes", label: "Informações" },
  { name: "grupos", label: "Grupos" },
  { name: "unidades", label: "Unidades" },
];

const products = ref([]);

const weekdays = [
  { value: 1, label: "Segunda" },
  { value: 2, label: "Terça" },
  { value: 3, label: "Quarta" },
  { value: 4, label: "Quinta" },
  { value: 5, label: "Sexta" },
  { value: 6, label: "Sábado" },
  { value: 0, label: "Domingo" },
];

const trimTime = (time) => (time ? time.slice(0, 5) : null);

const calculateEndTime = (startTime, durationHours) => {
  if (!/^\d{2}:\d{2}$/.test(startTime ?? "")) return null;
  const [hours, minutes] = startTime.split(":").map(Number);
  if (hours > 23 || minutes > 59) return null;
  const end =
    (hours * 60 + minutes + Math.round(Number(durationHours) * 60)) %
    (24 * 60);
  return `${String(Math.floor(end / 60)).padStart(2, "0")}:${String(
    end % 60,
  ).padStart(2, "0")}`;
};

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

const form = ref({
  name: props.package?.name ?? null,
  quantity_classes: props.package?.quantity_classes ?? null,
  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,
  class_duration_hours:
    (props.package?.class_duration_minutes ?? 120) / 60,
  weekday: props.package?.weekday ?? null,
  start_time: trimTime(props.package?.start_time),
  second_weekday: props.package?.second_weekday ?? null,
  second_start_time: trimTime(props.package?.second_start_time),
  materials: [{ product_id: null, quantity: 1, price: null }],
});

const secondWeekdayOptions = computed(() =>
  weekdays.filter((day) => day.value !== form.value.weekday),
);
const firstEndTime = computed(() =>
  calculateEndTime(form.value.start_time, form.value.class_duration_hours),
);
const secondEndTime = computed(() =>
  calculateEndTime(
    form.value.second_start_time,
    form.value.class_duration_hours,
  ),
);

watch(
  () => form.value.weekday,
  (weekday) => {
    if (form.value.second_weekday === weekday) {
      form.value.second_weekday = null;
    }
  },
);

const onProductSelected = (material) => {
  const option = productOptions.value.find(
    (o) => o.value === material.product_id,
  );
  if (option) material.price = option.price_sale;
};

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

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

// const contractMaterialValue = computed(() =>
//   form.value.materials.reduce((sum, m) => {
//     const qty = Number(m.quantity) || 0;
//     const price = Number(m.price) || 0;
//     return sum + qty * price;
//   }, 0)
// );

// Unidades tab
const unitSearch = ref("");
const units = ref([]);

// Grupos tab
const groupSearch = ref("");
const groups = ref([]);

// Set of unit IDs that are locked because they belong to a selected group
const lockedUnitIds = computed(() => {
  const ids = new Set();
  groups.value.forEach((g) => {
    if (g.visible && g.unit_ids) {
      g.unit_ids.forEach((id) => ids.add(id));
    }
  });
  return ids;
});

// When group visibility changes, force locked units to visible
watch(
  lockedUnitIds,
  (newLockedIds) => {
    units.value.forEach((u) => {
      if (newLockedIds.has(u.id)) {
        u.visible = true;
      }
    });
  },
  { deep: true },
);

const filteredUnits = computed(() => {
  const q = unitSearch.value.toLowerCase();
  if (!q) return units.value;
  return units.value.filter((unit) =>
    formatUnitName(unit).toLowerCase().includes(q),
  );
});

const setAllVisible = (visible) => {
  units.value.forEach((u) => {
    // Cannot hide a unit that is locked by a group
    if (!visible && lockedUnitIds.value.has(u.id)) return;
    u.visible = visible;
  });
};

const filteredGroups = computed(() => {
  const q = groupSearch.value.toLowerCase();
  if (!q) return groups.value;
  return groups.value.filter((g) =>
    g.name.toLowerCase().includes(q),
  );
});

const setAllGroupsVisible = (visible) => {
  groups.value.forEach((g) => (g.visible = visible));
};

onMounted(async () => {
  loadingUnits.value = true;
  loadingGroups.value = true;
  try {
    const [allUnits, allProducts, allGroups] = await Promise.all([
      getUnitsForSelect(),
      getProductsForSelect(),
      getGroupsForSelect(),
    ]);

    products.value = allProducts;

    let visibilityMap = {};
    let savedMaterials = null;
    let savedGroupIds = [];

    if (props.package?.id) {
      const pkg = await getPackage(props.package.id);
      (pkg.unit_visibilities ?? []).forEach((uv) => {
        visibilityMap[uv.unit_id] = uv.visible;
      });
      if (pkg.materials?.length) {
        savedMaterials = pkg.materials.map((m) => ({
          product_id: m.product_id,
          quantity: m.quantity,
          price: m.price,
        }));
      }
      savedGroupIds = pkg.group_ids ?? [];
    }

    // Build groups with visibility flag and their unit_ids
    groups.value = allGroups.map((g) => ({
      id: g.id,
      name: g.name,
      unit_ids: g.unit_ids ?? [],
      visible: savedGroupIds.includes(g.id),
    }));

    // Units locked by groups start visible = true
    const groupLockedIds = new Set();
    groups.value.forEach((g) => {
      if (g.visible) g.unit_ids.forEach((id) => groupLockedIds.add(id));
    });

    units.value = allUnits.map((u) => ({
      id: u.id,
      name: u.name,
      fantasy_name: u.fantasy_name,
      social_reason: u.social_reason,
      visible: groupLockedIds.has(u.id) ? true : (visibilityMap[u.id] ?? true),
    }));

    if (savedMaterials) {
      form.value.materials = savedMaterials;
    }
  } finally {
    loadingUnits.value = false;
    loadingGroups.value = false;
  }
});

const onOKClick = async () => {
  loading.value = true;
  try {
    const validMaterials = form.value.materials.filter((m) => m.product_id);

    const payload = {
      name: form.value.name,
      quantity_classes: form.value.quantity_classes,
      contract_value: form.value.contract_value,
      contract_register_value: form.value.contract_register_value,
      contrat_discount_value: form.value.contrat_discount_value,
      class_duration_minutes: Math.round(
        Number(form.value.class_duration_hours) * 60,
      ),
      weekday: form.value.weekday,
      start_time: form.value.start_time || null,
      second_weekday: form.value.second_weekday,
      second_start_time: form.value.second_start_time || null,
      group_ids: groups.value
        .filter((g) => g.visible)
        .map((g) => g.id),
      unit_visibilities: units.value.map((u) => ({
        unit_id: u.id,
        visible: u.visible,
      })),
      materials: validMaterials.map((m) => ({
        product_id: m.product_id,
        quantity: Number(m.quantity),
        price: Number(m.price),
      })),
    };

    const result = props.package?.id
      ? await updatePackage(props.package.id, payload)
      : await createPackage(payload);

    onDialogOK(result);
  } finally {
    loading.value = false;
  }
};
</script>

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