# [SKRIP 4.2: Batch tahan galat: menggabungkan kiriman lapangan, mencatat yang gagal]
# Penulis: Badar Mubarok Yogaswara
import csv
import glob
import os
import processing
from qgis.core import QgsProject, QgsVectorLayer, QgsCoordinateReferenceSystem

DATA = "D:/Latihan/paket-i4"
HASIL = "D:/Latihan/hasil_i4"
os.makedirs(HASIL, exist_ok=True)

CRS_TUJUAN = "EPSG:32749"
FIELD_WAJIB = ["Kondisi", "Tinggi_Phn", "Foto"]
log = []                    # satu baris catatan untuk tiap berkas: (berkas, status, keterangan)
bagus = []                  # layer yang lolos pemeriksaan

for jalur in sorted(glob.glob(DATA + "/Kiriman_Lapangan/*.gpkg")):
    nama = os.path.basename(jalur)
    try:
        layer = QgsVectorLayer(jalur, nama, "ogr")
        if not layer.isValid():
            raise ValueError("berkas rusak atau bukan GeoPackage")
        kurang = [f for f in FIELD_WAJIB if layer.fields().indexOf(f) < 0]
        if kurang:
            raise ValueError("field hilang: " + ", ".join(kurang))
        catatan = "sesuai"
        if layer.crs().authid() != CRS_TUJUAN:
            asal = layer.crs().authid()
            layer = processing.run("native:reprojectlayer", {
                "INPUT": layer, "TARGET_CRS": QgsCoordinateReferenceSystem(CRS_TUJUAN),
                "OUTPUT": "TEMPORARY_OUTPUT"})["OUTPUT"]
            catatan = "CRS %s diubah ke %s" % (asal, CRS_TUJUAN)
        bagus.append(layer)
        log.append((nama, "DITERIMA", "%d titik; %s" % (layer.featureCount(), catatan)))
    except Exception as e:                       # satu berkas gagal, yang lain tetap diproses
        log.append((nama, "DITOLAK", str(e)))

if not bagus:             # tanpa berkas lolos, penggabungan gagal; tampilkan dulu sebab penolakan
    for baris in log:
        print("%-22s %-9s %s" % baris)
    raise RuntimeError("Tidak ada berkas yang lolos pemeriksaan; penggabungan dibatalkan")

# Gabungkan yang lolos
gabungan = processing.run("native:mergevectorlayers", {
    "LAYERS": bagus, "CRS": QgsCoordinateReferenceSystem(CRS_TUJUAN),
    "OUTPUT": "TEMPORARY_OUTPUT"})["OUTPUT"]
gabungan.setName("Titik_Survei_Gabungan")
QgsProject.instance().addMapLayer(gabungan)

# Pemeriksaan keberadaan: titik yang tidak jatuh di dalam KPH mana pun patut dicurigai
batas = QgsVectorLayer(DATA + "/Batas_KPH.gpkg", "Batas_KPH", "ogr")
cek = processing.run("native:joinattributesbylocation", {
    "INPUT": gabungan, "JOIN": batas, "JOIN_FIELDS": ["NAMA_KPH"], "METHOD": 1,
    "PREDICATE": [0], "DISCARD_NONMATCHING": False, "OUTPUT": "TEMPORARY_OUTPUT"})["OUTPUT"]
luar = [f["Foto"] for f in cek.getFeatures() if not f["NAMA_KPH"]]
for foto in luar:
    log.append((foto, "CURIGA", "titik jatuh di luar semua KPH"))

# Laporan: layar dan berkas CSV
with open(HASIL + "/log_kiriman.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(["berkas", "status", "keterangan"])
    w.writerows(log)
for baris in log:
    print("%-22s %-9s %s" % baris)
print("Ringkasan: %d diterima, %d ditolak, %d curiga; total titik gabungan %d" % (
    sum(1 for b in log if b[1] == "DITERIMA"), sum(1 for b in log if b[1] == "DITOLAK"),
    len(luar), gabungan.featureCount()))
