<template>
  <div class="layout-px-spacing">
    <teleport to="#breadcrumb">
      <ul class="navbar-nav flex-row">
        <li>
          <div class="page-header">
            <nav class="breadcrumb-one" aria-label="breadcrumb">
              <ol class="breadcrumb">
                <li class="breadcrumb-item">
                  <a href="javascript:;">{{ $t("lavanderia.area.breadcrumb_parent") }}</a>
                </li>
                <li class="breadcrumb-item active" aria-current="page">
                  <span>{{ $t("lavanderia.area.breadcrumb_current", { area: areaDisplayName }) }}</span>
                </li>
              </ol>
            </nav>
          </div>
        </li>
      </ul>
    </teleport>

    <div class="row layout-top-spacing">
      <div class="col-xl-12 col-lg-12 col-sm-12 layout-spacing">
        <div class="panel p-3">
          <div class="row">
            <div class="col-xl-10 col-lg-10 mx-auto">
              <h3 class="mb-2">{{ $t("lavanderia.area.title") }}</h3>
              <p class="text-muted mb-3">
                {{ $t("lavanderia.area.subtitle", { code: areaDisplayName }) }}
              </p>

              <div v-if="areaMeta?.requires_scan_twice" class="alert alert-info py-2 mb-3">
                {{ $t("lavanderia.area.requires_two_scans") }}
              </div>

              <div class="card mb-3">
                <div class="card-body">
                  <label class="form-label fw-bold" for="tibu-scan-input">{{
                    $t("lavanderia.area.scan_label")
                  }}</label>
                  <div class="form-group mb-3">
                    <label class="form-label">{{ $t("lavanderia.escanear.operator_select_label") }} *</label>
                    <select
                      v-model.number="selectedOperatorId"
                      class="form-select"
                      :disabled="operatorsLoading || !operators.length"
                    >
                      <option :value="null" disabled>{{ $t("lavanderia.escanear.operator_select_placeholder") }}</option>
                      <option v-for="op in operators" :key="op.id" :value="op.id">
                        {{ op.name }}
                      </option>
                    </select>
                  </div>
                  <input
                    id="tibu-scan-input"
                    ref="scanInputRef"
                    type="text"
                    class="form-control form-control-lg text-center"
                    autocomplete="off"
                    :placeholder="$t('lavanderia.area.scan_placeholder')"
                    v-model="scanValue"
                    :disabled="loading"
                    @keyup.enter="onScan"
                  />
                  <p class="small text-muted mt-2 mb-3">
                    {{ $t("lavanderia.area.scan_help") }}
                  </p>
                  <button
                    type="button"
                    class="btn btn-primary btn-lg w-100"
                    :disabled="loading || !scanValue.trim() || !selectedOperatorId"
                    @click="onScan"
                  >
                    {{ loading ? $t("lavanderia.area.scan_loading") : $t("lavanderia.area.scan_submit") }}
                  </button>
                </div>
              </div>

              <div v-if="lastSuccessHint" class="alert" :class="lastSuccessAlertClass" role="status">
                <strong>{{ lastSuccessHint.title }}</strong>
                <div class="small mt-1">{{ lastSuccessHint.body }}</div>
              </div>

              <div v-if="error" class="alert alert-danger" role="alert">
                {{ error }}
              </div>
              <div
                v-if="validationErrors && Object.keys(validationErrors).length"
                class="alert alert-warning"
                role="alert"
              >
                <ul class="mb-0 ps-3">
                  <li v-for="(msgs, key) in validationErrors" :key="key">
                    <span v-for="(m, i) in msgs" :key="i">{{ m }}</span>
                  </li>
                </ul>
              </div>

              <div class="card">
                <div class="card-header">
                  <h5 class="mb-0">{{ $t("lavanderia.area.recent_events") }}</h5>
                </div>
                <div class="card-body p-0">
                  <ul v-if="recentEvents.length" class="list-group list-group-flush">
                    <li
                      v-for="(ev, idx) in recentEvents"
                      :key="idx"
                      class="list-group-item d-flex justify-content-between align-items-start flex-wrap"
                    >
                      <div>
                        <span
                          class="badge me-2"
                          :class="ev.ok ? 'bg-success' : 'bg-danger'"
                          >{{ ev.ok ? $t("lavanderia.area.event_ok") : $t("lavanderia.area.event_fail") }}</span
                        >
                        <template v-if="ev.ok">
                          <strong>{{ ev.folio }}</strong>
                          <span class="text-muted ms-1">
                            · {{ sequenceLabel(ev.sequence) }}
                          </span>
                        </template>
                        <template v-else>
                          <span class="text-danger">{{ ev.message }}</span>
                        </template>
                      </div>
                      <small class="text-muted">{{ formatTime(ev.at) }}</small>
                    </li>
                  </ul>
                  <div v-else class="p-3 text-muted small">
                    {{ $t("lavanderia.area.recent_empty") }}
                  </div>
                </div>
              </div>

              <div v-if="switchableAreas.length > 1" class="mt-3">
                <span class="text-muted small d-block mb-2">{{ $t("lavanderia.area.switch_area") }}</span>
                <div class="d-flex flex-wrap gap-2">
                  <router-link
                    v-for="c in switchableAreas"
                    :key="c"
                    class="btn btn-sm"
                    :class="c === areaCode ? 'btn-primary' : 'btn-outline-secondary'"
                    :to="{ name: 'lavanderia-area-router', params: { areaCode: c } }"
                  >
                    {{ $t(`lavanderia.area.codes.${c}`) }}
                  </router-link>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <loading
      v-model:active="loading"
      :can-cancel="false"
      :is-full-page="true"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from "vue";
import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import Loading from "vue-loading-overlay";
import "vue-loading-overlay/dist/css/index.css";
import { usePageTitle } from "@/composables/use-meta";
import { useLaundryScan } from "@/composables/useLaundryScan";
import { useScanOperators } from "@/composables/useScanOperators";
import * as AreaRepository from "@/repositories/AreaRepository";
import * as UserRepository from "@/repositories/UserRepository";
import { TIBU_AREA_CODES } from "@/constants/tibuAreas";
import { usePermissions } from "@/composables/use-permissions";

const route = useRoute();
const { t } = useI18n();
const { hasPermission, loadPermissions } = usePermissions();

const areaCode = computed(() => String(route.params.areaCode || "").trim());

const scanInputRef = ref(null);
const scanValue = ref("");
const areaMeta = ref(null);
const recentEvents = ref([]);
const currentUser = ref(null);
const selectedOperatorId = ref(null);

const { operators, loading: operatorsLoading, load: loadOperators } = useScanOperators(areaCode);

const { loading, error, validationErrors, lastData, submitScan, reset } = useLaundryScan();

const MAX_EVENTS = 25;

const areaDisplayName = computed(() => {
  const code = areaCode.value;
  if (!code) return "";
  const key = `lavanderia.area.codes.${code}`;
  const translated = t(key);
  return translated === key ? code : translated;
});

const lastSuccessHint = computed(() => {
  const d = lastData.value;
  if (!d || d.scan_sequence == null) return null;
  const seq = Number(d.scan_sequence);
  if (seq === 1) {
    return {
      title: t("lavanderia.area.scan_first_title"),
      body: t("lavanderia.area.scan_first_body"),
    };
  }
  if (seq === 2) {
    return {
      title: t("lavanderia.area.scan_second_title"),
      body: t("lavanderia.area.scan_second_body"),
    };
  }
  return {
    title: t("lavanderia.area.scan_registered"),
    body: d.orden?.folio_unico ? String(d.orden.folio_unico) : "",
  };
});

const lastSuccessAlertClass = computed(() => {
  const d = lastData.value;
  if (!d || d.scan_sequence == null) return "alert-success";
  return Number(d.scan_sequence) === 2 ? "alert-primary" : "alert-success";
});

const switchableAreas = computed(() =>
  TIBU_AREA_CODES.filter((c) => hasPermission(`area.${c}.operate`))
);

async function focusScan() {
  await nextTick();
  scanInputRef.value?.focus?.();
  scanInputRef.value?.select?.();
}

async function loadAreaMeta() {
  areaMeta.value = null;
  try {
    const body = await AreaRepository.getAll();
    const list = body?.data;
    if (!Array.isArray(list)) return;
    areaMeta.value = list.find((a) => a.code === areaCode.value) || null;
  } catch {
    /* área desconocida: el backend validará al escanear */
  }
}

function formatTime(iso) {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleString("es-MX");
  } catch {
    return iso;
  }
}

function sequenceLabel(seq) {
  if (seq === 1) return t("lavanderia.area.seq_first");
  if (seq === 2) return t("lavanderia.area.seq_second");
  return String(seq);
}

function pushEvent(ev) {
  recentEvents.value = [ev, ...recentEvents.value].slice(0, MAX_EVENTS);
}

async function onScan() {
  const raw = scanValue.value.trim();
  if (!raw || !areaCode.value || !selectedOperatorId.value) return;

  try {
    const body = await submitScan({
      qrOrFolio: raw,
      areaCode: areaCode.value,
      operatorUserId: selectedOperatorId.value,
    });
    const data = body?.data ?? lastData.value;
    const folio = data?.orden?.folio_unico ?? "";
    const sequence = data?.scan_sequence != null ? Number(data.scan_sequence) : null;
    pushEvent({
      ok: true,
      at: new Date().toISOString(),
      folio,
      sequence,
    });
    scanValue.value = "";
    await focusScan();
  } catch (e) {
    const msg =
      e?.response?.data?.message ||
      error.value ||
      t("lavanderia.area.scan_error_generic");
    pushEvent({
      ok: false,
      at: new Date().toISOString(),
      message: msg,
    });
    await focusScan();
  }
}

function pickDefaultOperator() {
  const uid = currentUser.value?.id;
  const list = operators.value;
  if (!list.length) {
    selectedOperatorId.value = null;
    return;
  }
  if (uid && list.some((o) => o.id === uid)) {
    selectedOperatorId.value = uid;
    return;
  }
  selectedOperatorId.value = list[0].id;
}

watch(operators, () => pickDefaultOperator());

watch(
  () => route.params.areaCode,
  async () => {
    reset();
    scanValue.value = "";
    await loadAreaMeta();
    await loadOperators();
    pickDefaultOperator();
    await focusScan();
  }
);

onMounted(async () => {
  await loadPermissions();
  try {
    currentUser.value = await UserRepository.getuser();
  } catch {
    currentUser.value = null;
  }
  await loadAreaMeta();
  await loadOperators();
  pickDefaultOperator();
  await focusScan();
});

usePageTitle(
  computed(() =>
    t("lavanderia.area.page_title", { area: areaDisplayName.value || areaCode.value })
  )
);
</script>

<style scoped>
.card {
  transition: all 0.2s ease;
}
</style>
