package hr.com.port.ips.eracun.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import org.apache.log4j.Logger;

public class EracunStatusService {
    static Logger logger = Logger.getLogger(EracunStatusService.class);

    /*
     * Ažurira statuse dokumenta (lokalni/transportni/procesni) i upisuje log promjene.
     *
     * @param conn                    Veza na bazu
     * @param izlazni                 Oznaka dokumenta (true = izlazni, false = ulazni)
     * @param godina                  Poslovna godina
     * @param posrednik               ID posrednika
     * @param vrstaDokumenta          Vrsta dokumenta
     * @param onu                     Oznaka naplatnog uređaja
     * @param opp                     Oznaka poslovnog prostora
     * @param broj                    Broj dokumenta
     *
     * @param transportniStatusId     Transportni status ID (iz posrednika)
     * @param transportniStatusNaziv  Transportni status naziv (iz posrednika)
     * @param procesniStatusId        Procesni/poslovni status ID (iz posrednika)
     * @param procesniStatusNaziv     Procesni/poslovni status naziv (iz posrednika)
     * @param lokalniStatusId         Lokalni (interni) status ID
     * @param lokalniStatusNaziv      Lokalni (interni) status naziv
     *
     * @param porukaGreske            Opis greške (može biti null)
     *
     * // Polja za log zapis:
     * @param electronicId            ElectronicId (može biti null)
     * @param izvor                   Izvor promjene (npr. "MER", "LOCAL", "SYSTEM")
     * @param akcija                  Akcija (npr. "CREATE", "SEND", "QUERY", "RECEIVE", "UPDATE")
     * @param opis                    Slobodan opis događaja (može biti null)
     * @param putanjaXml              Putanja XML datoteke povezana s događajem (može biti null)
     * @param oibOperatera            OIB operatera koji je pokrenuo promjenu (može biti null)
     */
    public static void azurirajStatus(
            Connection conn,
            boolean izlazni,
            int godina, int posrednik, int vrstaDokumenta, int onu, int opp, int broj,
            // novi setovi statusa
            Integer transportniStatusId, String transportniStatusNaziv,
            Integer procesniStatusId,    String procesniStatusNaziv,
            Integer lokalniStatusId,     String lokalniStatusNaziv,
            // meta
            String porukaGreske,
            // opcionalno za log
            Long electronicId, String izvor, String akcija, String opis, String putanjaXml, String oibOperatera
    ) throws SQLException {

        final Timestamp now = new Timestamp(System.currentTimeMillis());

        // 1) update glavne tablice
        final String updateMain =
                "UPDATE eracun_dokument SET " +
                "  transportni_status_id = ?, transportni_status_naziv = ?, " +
                "  procesni_status_id    = ?, procesni_status_naziv    = ?, " +
                "  lokalni_status_id     = ?, lokalni_status_naziv     = ?, " +
                "  datum_zadnjeg_statusa = ?, " +
                "  poruka_greske         = ? " +
                "WHERE izlazni=? AND godina=? AND posrednik=? AND vrsta_dokumenta=? AND onu=? AND opp=? AND broj=?";

        try (PreparedStatement ps = conn.prepareStatement(updateMain)) {
            ps.setObject(1, transportniStatusId, java.sql.Types.INTEGER);
            ps.setString(2, transportniStatusNaziv);
            ps.setObject(3, procesniStatusId,    java.sql.Types.INTEGER);
            ps.setString(4, procesniStatusNaziv);
            ps.setObject(5, lokalniStatusId,     java.sql.Types.INTEGER);
            ps.setString(6, lokalniStatusNaziv);
            ps.setTimestamp(7, now);
            ps.setString(8, porukaGreske);

            ps.setBoolean(9, izlazni);
            ps.setInt(10, godina);
            ps.setInt(11, posrednik);
            ps.setInt(12, vrstaDokumenta);
            ps.setInt(13, onu);
            ps.setInt(14, opp);
            ps.setInt(15, broj);

            ps.executeUpdate();
        }

        // 2) insert u log tablicu (usklađeno: uključuje 'izlazni')
        final String insertLog =
                "INSERT INTO eracun_dokument_log (" +
                "  izlazni, godina, posrednik, vrsta_dokumenta, onu, opp, broj," +
                "  electronic_id," +
                "  lokalni_status_id, lokalni_status_naziv," +
                "  transportni_status_id, transportni_status_naziv," +
                "  procesni_status_id, procesni_status_naziv," +
                "  datum_statusa, datum_promjene," +
                "  poruka_greske, opis, putanja_xml, izvor, akcija, oib_operatera" +
                ") VALUES (?,?,?,?,?,?," +
                "          ?, " +
                "          ?,?, " +
                "          ?,?, " +
                "          ?,?, " +
                "          ?,?, " +
                "          ?,?,?,?, ?, ?)";

        try (PreparedStatement ps = conn.prepareStatement(insertLog)) {
            ps.setBoolean(1, izlazni);
            ps.setInt(2,  godina);
            ps.setInt(3,  posrednik);
            ps.setInt(4,  vrstaDokumenta);
            ps.setInt(5,  onu);
            ps.setInt(6,  opp);
            ps.setInt(7,  broj);

            ps.setObject(8, electronicId, java.sql.Types.BIGINT);

            ps.setObject(9,  lokalniStatusId, java.sql.Types.INTEGER);
            ps.setString(10, lokalniStatusNaziv);

            ps.setObject(11, transportniStatusId, java.sql.Types.INTEGER);
            ps.setString(12, transportniStatusNaziv);

            ps.setObject(13, procesniStatusId, java.sql.Types.INTEGER);
            ps.setString(14, procesniStatusNaziv);

            ps.setTimestamp(15, now); // datum_statusa
            ps.setTimestamp(16, now); // datum_promjene

            ps.setString(17, porukaGreske);
            ps.setString(18, opis);
            ps.setString(19, putanjaXml);
            ps.setString(20, izvor);
            ps.setString(21, akcija);
            ps.setString(22, oibOperatera);

            ps.executeUpdate();
        }
    }

    // EracunStatusService.java – usklađeno: dodan 'izlazni' i u WHERE i u log
    public static void azurirajProcesniStatus(
            Connection conn,
            boolean izlazni,
            int godina, int posrednik, int vrstaDokumenta, int onu, int opp, int broj,
            Integer procesniStatusId, String procesniStatusNaziv,
            Timestamp datumStatusa,
            String porukaGreske,
            Long electronicId, String izvor, String akcija, String opis,
            String putanjaXml, String oibOperatera
    ) throws SQLException {

        final Timestamp now = new Timestamp(System.currentTimeMillis());

        final String up =
                "UPDATE eracun_dokument SET " +
                "  procesni_status_id = ?, procesni_status_naziv = ?, " +
                "  datum_zadnjeg_statusa = ?, poruka_greske = ? " +
                "WHERE izlazni=? AND godina=? AND posrednik=? AND vrsta_dokumenta=? AND onu=? AND opp=? AND broj=?";
        try (PreparedStatement ps = conn.prepareStatement(up)) {
            ps.setObject(1, procesniStatusId, java.sql.Types.INTEGER);
            ps.setString(2, procesniStatusNaziv);
            ps.setTimestamp(3, datumStatusa != null ? datumStatusa : now);
            ps.setString(4, porukaGreske);

            ps.setBoolean(5, izlazni);
            ps.setInt(6, godina);
            ps.setInt(7, posrednik);
            ps.setInt(8, vrstaDokumenta);
            ps.setInt(9, onu);
            ps.setInt(10, opp);
            ps.setInt(11, broj);

            ps.executeUpdate();
        }

        final String ins =
                "INSERT INTO eracun_dokument_log (" +
                "  izlazni, godina, posrednik, vrsta_dokumenta, onu, opp, broj, electronic_id, " +
                "  lokalni_status_id, lokalni_status_naziv, " +
                "  transportni_status_id, transportni_status_naziv, " +
                "  procesni_status_id, procesni_status_naziv, " +
                "  datum_statusa, datum_promjene, poruka_greske, opis, putanja_xml, izvor, akcija, oib_operatera" +
                ") VALUES (?,?,?,?,?,?," +
                " ?, " +
                " ?,?, " +          // lokalni null
                " ?,?, " +          // transportni null
                " ?,?, " +          // procesni
                " ?,?, " +          // datumi
                " ?,?,?, ?, ?, ?)";
        try (PreparedStatement ps = conn.prepareStatement(ins)) {
            ps.setBoolean(1, izlazni);
            ps.setInt(2, godina); ps.setInt(3, posrednik); ps.setInt(4, vrstaDokumenta);
            ps.setInt(5, onu);    ps.setInt(6, opp);       ps.setInt(7, broj);

            ps.setObject(8, electronicId, java.sql.Types.BIGINT);

            // lokalni null
            ps.setObject(9,  null, java.sql.Types.INTEGER);
            ps.setString(10, null);

            // transportni null
            ps.setObject(11, null, java.sql.Types.INTEGER);
            ps.setString(12, null);

            // procesni
            ps.setObject(13, procesniStatusId, java.sql.Types.INTEGER);
            ps.setString(14, procesniStatusNaziv);

            Timestamp ds = (datumStatusa != null ? datumStatusa : now);
            ps.setTimestamp(15, ds);   // datum_statusa
            ps.setTimestamp(16, now);  // datum_promjene

            ps.setString(17, porukaGreske);
            ps.setString(18, opis);
            ps.setString(19, putanjaXml);
            ps.setString(20, izvor);
            ps.setString(21, akcija);
            ps.setString(22, oibOperatera);

            ps.executeUpdate();
        }
    }
}