package hr.com.port.ips.eracun.helper;

import hr.com.port.functions.Functions;
import java.sql.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class DocumentNrResolver {

    private static final Logger logger = LoggerFactory.getLogger(DocumentNrResolver.class);

    // Dozvoljeni separatori: "/" ili "-"
    // Format: <broj>/<OPP>/<uređaj>
    // broj i uređaj su numerički; OPP = [A-Za-z0-9_.-]+ (po potrebi proširi)
    private static final Pattern P = Pattern.compile(
        "^\\s*(\\d+)\\s*[/-]\\s*([A-Za-z0-9_.-]+)\\s*[/-]\\s*(\\d+)\\s*$"
    );

    private DocumentNrResolver() {}

    // Rezultat parsiranja i mapiranja.
    public static final class Result {
        public Integer broj;           // broj računa
        public String oppOznaka;       // oznaka poslovnog prostora
        public Integer uredjaj;        // oznaka naplatnog uređaja (broj)
        public Integer oppId;          // ID iz tablice opp (ako pronađen)
        public Integer onuId;          // ID iz tablice onu (ako pronađen)

        public boolean isFullyResolved() {
            return oppId != null && onuId != null && broj != null;
        }
    }

    // Parsira i vraća osnovne dijelove bez DB pristupa.
    public static Result parseOnly(String documentNr) {
        if (documentNr == null) return null;
        Matcher m = P.matcher(documentNr);
        if (!m.matches()) return null;

        Result r = new Result();
        try {
            r.broj = Integer.valueOf(m.group(1));
        } catch (NumberFormatException ex) {
            return null;
        }
        r.oppOznaka = m.group(2);
        try {
            r.uredjaj = Integer.valueOf(m.group(3));
        } catch (NumberFormatException ex) {
            return null;
        }
        return r;
    }
    
    //  Parsira DocumentNr i pokuša mapirati OPP/ONU ID-ove preko oznake.
    //  conn otvorena veza (ne zatvara se u metodi)
    public static Result resolve(Connection conn, String documentNr) {
        Result r = parseOnly(documentNr);
        if (r == null) {
            logger.debug("DocumentNr nije prepoznat: '{}'", documentNr);
            return null;
        }

        // OPP.id po opp.oznaka
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement("SELECT id FROM opp WHERE oznaka = ?");
            ps.setString(1, r.oppOznaka);
            rs = ps.executeQuery();
            if (rs.next()) {
                r.oppId = rs.getInt(1);
            }
        } catch (SQLException ex) {
            logger.error(new Functions().logging(ex));
        } finally {
            closeQuietly(rs);
            closeQuietly(ps);
        }

        // ONU.id po onu.oznaka i opp.id
		if(r.oppId == null){
			r.onuId = null;
		}else{
			try {
				ps = conn.prepareStatement("SELECT id FROM onu WHERE opp = ? AND oznaka = ?");
				ps.setInt(1, r.oppId);
				ps.setString(2, r.uredjaj.toString());
				rs = ps.executeQuery();
				if (rs.next()) {
					r.onuId = rs.getInt(1);
				}
			} catch (SQLException ex) {
				logger.error(new Functions().logging(ex));
			} finally {
				closeQuietly(rs);
				closeQuietly(ps);
			}
		}
        logger.debug("DocumentNr resolve -> broj=" + r.broj + ", oppOznaka=" + r.oppOznaka + ", uredjaj=" + r.uredjaj + ", oppId=" + r.oppId + ", onuId=" + r.onuId);        
        return r;
    }

    private static void closeQuietly(AutoCloseable c) {
        if (c != null) try { c.close(); } catch (Exception ignore) {}
    }
	
	// TEST REGEX-a
	public static void main(String[] args) {
		String[] samples = {
			"77/SJ/1",
			"77-SJ-1",
			"  1234 / A1 / 2 ",
			"9/PP-01/5",
			"001/PROSTOR.2/10",
			"badformat",
			"12//3",
			"12/SJ/"
		};

		System.out.println("=== DocumentNrResolver demo (parseOnly) ===");
		for (String s : samples) {
			Result r = parseOnly(s);
			if (r == null) {
				System.out.printf("IN: %-18s  ->  PARSE FAIL%n", s);
			} else {
				System.out.printf("IN: %-18s  ->  broj=%-5d oppOznaka=%-10s uredjaj=%d%n",
						s, r.broj, r.oppOznaka, r.uredjaj);
			}
		}
	}
}