import { ref, computed } from "vue";
import * as OrdenLavanderiaRepository from "@/repositories/OrdenLavanderiaRepository";
import * as TicketRepository from "@/repositories/TicketRepository";
import * as VentasRepository from "@/repositories/VentasRepository";
import { useEtiquetaBolsaImpresion } from "@/composables/useEtiquetaBolsaImpresion";
import ApiService from "@/services/ApiService";
import { usePermissions } from "@/composables/use-permissions";

/**
 * Historial de órdenes/tickets: filtros, paginación servidor, reimpresión PDF (servidor) y export CSV (§25).
 */
export function useTickets() {
  const { loadPermissions, hasPermission } = usePermissions();
  const loading = ref(false);
  const reprintingId = ref(null);
  const error = ref(null);
  /** Objeto paginador Laravel (current_page, data, last_page, total, …) */
  const paginator = ref(null);
  const tiposServicio = ref([]);
  const selectedIds = ref([]);

  const filters = ref({
    created_from: "",
    created_to: "",
    cliente_nombre: "",
    folio_unico: "",
    estatus: "",
    tipo_servicio_id: "",
    is_priority: "",
    caja_id: "",
    page: 1,
    per_page: 20,
  });

  const canExportCsv = computed(() => hasPermission("reportes.ver"));

  const rows = computed(() => {
    const p = paginator.value;
    if (!p || !Array.isArray(p.data)) return [];
    return p.data;
  });

  function buildQueryParams() {
    const f = filters.value;
    const params = {
      page: f.page,
      per_page: f.per_page,
    };
    if (f.created_from) params.created_from = f.created_from;
    if (f.created_to) params.created_to = f.created_to;
    if (f.cliente_nombre?.trim()) params.cliente_nombre = f.cliente_nombre.trim();
    if (f.folio_unico?.trim()) params.folio_unico = f.folio_unico.trim();
    if (f.estatus) params.estatus = f.estatus;
    if (f.tipo_servicio_id !== "" && f.tipo_servicio_id != null) {
      params.tipo_servicio_id = f.tipo_servicio_id;
    }
    if (f.is_priority !== "" && f.is_priority != null) {
      params.is_priority = f.is_priority === "1" || f.is_priority === true ? 1 : 0;
    }
    if (f.caja_id !== "" && f.caja_id != null && String(f.caja_id).trim() !== "") {
      const n = Number(f.caja_id);
      if (!Number.isNaN(n) && n > 0) {
        params.caja_id = n;
      }
    }
    return params;
  }

  async function loadTiposServicio() {
    try {
      const body = await VentasRepository.getPosCatalog();
      const d = body?.data || body;
      tiposServicio.value = d?.tipos_servicio || [];
    } catch {
      tiposServicio.value = [];
    }
  }

  async function fetchPage() {
    loading.value = true;
    error.value = null;
    try {
      const body = await OrdenLavanderiaRepository.getAll(buildQueryParams());
      paginator.value = body?.data ?? null;
      selectedIds.value = [];
    } catch (e) {
      paginator.value = null;
      error.value = e.response?.data?.message || e.message || "Error";
      throw e;
    } finally {
      loading.value = false;
    }
  }

  function applyFilters() {
    filters.value.page = 1;
    return fetchPage();
  }

  function goToPage(n) {
    const last = paginator.value?.last_page || 1;
    const p = Math.min(Math.max(1, n), last);
    filters.value.page = p;
    return fetchPage();
  }

  function resetFilters() {
    filters.value = {
      created_from: "",
      created_to: "",
      cliente_nombre: "",
      folio_unico: "",
      estatus: "",
      tipo_servicio_id: "",
      is_priority: "",
      caja_id: "",
      page: 1,
      per_page: 20,
    };
    return fetchPage();
  }

  function toggleRow(id) {
    const n = Number(id);
    const i = selectedIds.value.indexOf(n);
    if (i === -1) {
      selectedIds.value = [...selectedIds.value, n];
    } else {
      selectedIds.value = selectedIds.value.filter((x) => x !== n);
    }
  }

  function rowSelected(id) {
    return selectedIds.value.includes(Number(id));
  }

  function selectAllOnPage() {
    const ids = rows.value.map((r) => r.id);
    selectedIds.value = [...new Set([...selectedIds.value, ...ids])];
  }

  function clearSelection() {
    selectedIds.value = [];
  }

  async function bulkReprintServer() {
    const ids = [...selectedIds.value];
    if (!ids.length) return;
    for (const id of ids) {
      try {
        await reprintTicketThermal(id);
      } catch {
        /* continuar con el siguiente */
      }
      await new Promise((r) => setTimeout(r, 400));
    }
  }

  async function downloadExportCsv() {
    const params = { ...buildQueryParams() };
    delete params.page;
    delete params.per_page;
    const res = await OrdenLavanderiaRepository.exportHistorialCsv(params);
    const blob = res.data;
    const cd = res.headers["content-disposition"] || res.headers["Content-Disposition"];
    let filename = "ordenes-historial.csv";
    if (cd) {
      const m = String(cd).match(/filename\*?=(?:UTF-8'')?["']?([^"';]+)/i) || String(cd).match(/filename="([^"]+)"/i);
      if (m?.[1]) {
        try {
          filename = decodeURIComponent(m[1].replace(/"/g, "").trim());
        } catch {
          filename = m[1].replace(/"/g, "").trim();
        }
      }
    }
    const url = URL.createObjectURL(blob instanceof Blob ? blob : new Blob([blob]));
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(url);
  }

  async function reprintTicketThermal(ordenId) {
    reprintingId.value = ordenId;
    try {
      const body = await TicketRepository.reimprimirTicket(ordenId, null, { posReception: true });
      if (body?.success || body?.impresion?.success) {
        return { success: true, message: body.message || body.impresion?.message };
      }
      throw new Error(body?.impresion?.error || body?.message || "Error al imprimir");
    } finally {
      reprintingId.value = null;
    }
  }

  async function reprintLabelThermal(ordenId, options = {}) {
    const { imprimirEtiquetaTermica } = useEtiquetaBolsaImpresion();
    reprintingId.value = ordenId;
    try {
      return await imprimirEtiquetaTermica(ordenId, { indice: 1, todas: false, ...options });
    } finally {
      reprintingId.value = null;
    }
  }

  async function reprintTicketServerPdf(ordenId) {
    reprintingId.value = ordenId;
    try {
      const res = await ApiService.get(`lavanderia/ordenes/${ordenId}/ticket-pdf`, { responseType: "blob" });
      const url = URL.createObjectURL(new Blob([res.data], { type: "application/pdf" }));
      window.open(url, "_blank");
    } finally {
      reprintingId.value = null;
    }
  }

  async function initTickets() {
    await loadPermissions();
    await loadTiposServicio();
    await fetchPage();
  }

  return {
    loading,
    error,
    paginator,
    filters,
    rows,
    tiposServicio,
    selectedIds,
    canExportCsv,
    loadTiposServicio,
    fetchPage,
    applyFilters,
    goToPage,
    resetFilters,
    reprintTicketThermal,
    reprintLabelThermal,
    reprintTicketServerPdf,
    reprintingId,
    toggleRow,
    rowSelected,
    selectAllOnPage,
    clearSelection,
    bulkReprintServer,
    downloadExportCsv,
    initTickets,
  };
}
