import type { RowDataPacket } from "mysql2";

import { db } from "@/src/lib/db";
import type { Giacenza, GiacenzePerArticolo } from "@/src/types/giacenza";

type GiacenzaRow = Giacenza & RowDataPacket;

export async function getGiacenzeByMagazzino(magazzinoId: number): Promise<Giacenza[]> {
  const [rows] = await db.execute<GiacenzaRow[]>(
    `SELECT 
      g.id,
      g.articolo_id,
      g.id_magazzino,
      g.quantita,
      a.codice AS articolo_codice,
      a.descrizione AS articolo_descrizione,
      m.descrizione AS magazzino_descrizione,
      s.descrizione AS stabilimento_descrizione
    FROM giacenze g
    LEFT JOIN articoli a ON g.articolo_id = a.id
    LEFT JOIN magazzini m ON g.id_magazzino = m.id
    LEFT JOIN stabilimenti s ON m.id_stabilimento = s.id
    WHERE g.id_magazzino = :magazzinoId
    ORDER BY a.descrizione ASC`,
    { magazzinoId }
  );

  return rows.map((row) => ({
    id: row.id,
    articolo_id: row.articolo_id,
    id_magazzino: row.id_magazzino,
    quantita: Number(row.quantita) || 0,
    articolo_codice: row.articolo_codice,
    articolo_descrizione: row.articolo_descrizione,
    magazzino_descrizione: row.magazzino_descrizione,
    stabilimento_descrizione: row.stabilimento_descrizione,
  }));
}

export async function getGiacenzeByStabilimento(stabilimentoId: number): Promise<Giacenza[]> {
  const [rows] = await db.execute<GiacenzaRow[]>(
    `SELECT 
      g.id,
      g.articolo_id,
      g.id_magazzino,
      g.quantita,
      a.codice AS articolo_codice,
      a.descrizione AS articolo_descrizione,
      m.descrizione AS magazzino_descrizione,
      s.descrizione AS stabilimento_descrizione
    FROM giacenze g
    LEFT JOIN articoli a ON g.articolo_id = a.id
    LEFT JOIN magazzini m ON g.id_magazzino = m.id
    LEFT JOIN stabilimenti s ON m.id_stabilimento = s.id
    WHERE m.id_stabilimento = :stabilimentoId
    ORDER BY a.descrizione ASC`,
    { stabilimentoId }
  );

  return rows.map((row) => ({
    id: row.id,
    articolo_id: row.articolo_id,
    id_magazzino: row.id_magazzino,
    quantita: Number(row.quantita) || 0,
    articolo_codice: row.articolo_codice,
    articolo_descrizione: row.articolo_descrizione,
    magazzino_descrizione: row.magazzino_descrizione,
    stabilimento_descrizione: row.stabilimento_descrizione,
  }));
}

export async function getGiacenzeMapByMagazzino(magazzinoId: number): Promise<GiacenzePerArticolo> {
  const giacenze = await getGiacenzeByMagazzino(magazzinoId);
  
  const map: GiacenzePerArticolo = {};
  for (const g of giacenze) {
    map[g.articolo_id] = g.quantita;
  }
  
  return map;
}

export async function getGiacenzeMapByStabilimento(stabilimentoId: number): Promise<GiacenzePerArticolo> {
  const giacenze = await getGiacenzeByStabilimento(stabilimentoId);
  
  const map: GiacenzePerArticolo = {};
  for (const g of giacenze) {
    if (!map[g.articolo_id]) {
      map[g.articolo_id] = 0;
    }
    map[g.articolo_id] += g.quantita;
  }
  
  return map;
}

export async function getGiacenzaArticolo(articoloId: number): Promise<Giacenza[]> {
  const [rows] = await db.execute<GiacenzaRow[]>(
    `SELECT 
      g.id,
      g.articolo_id,
      g.id_magazzino,
      g.quantita,
      m.descrizione AS magazzino_descrizione,
      s.descrizione AS stabilimento_descrizione
    FROM giacenze g
    LEFT JOIN magazzini m ON g.id_magazzino = m.id
    LEFT JOIN stabilimenti s ON m.id_stabilimento = s.id
    WHERE g.articolo_id = :articoloId
    ORDER BY s.descrizione, m.descrizione`,
    { articoloId }
  );

  return rows.map((row) => ({
    id: row.id,
    articolo_id: row.articolo_id,
    id_magazzino: row.id_magazzino,
    quantita: Number(row.quantita) || 0,
    magazzino_descrizione: row.magazzino_descrizione,
    stabilimento_descrizione: row.stabilimento_descrizione,
  }));
}
