# [SKRIP 6.1: Membangun model "Sempadan Sungai per KPH" lewat Python, simpan sebagai .model3]
# Penulis: Badar Mubarok Yogaswara
# Model ini sama dengan yang bisa Anda gambar di Graphical Modeler; ini hanya cara lain membuatnya.
import os
from qgis.core import (QgsProcessing, QgsProcessingModelAlgorithm, QgsProcessingModelChildAlgorithm,
                       QgsProcessingModelChildParameterSource as Sumber, QgsProcessingModelParameter,
                       QgsProcessingModelOutput, QgsProcessingModelChildDependency,
                       QgsProcessingParameterVectorLayer, QgsProcessingParameterNumber)

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

m = QgsProcessingModelAlgorithm("Sempadan Sungai per KPH", "Kehutanan")

# --- Masukan model (yang diisi pengguna saat model dijalankan)
m.addModelParameter(QgsProcessingParameterVectorLayer(
    "KPH", "Layer batas KPH", [QgsProcessing.TypeVectorPolygon]), QgsProcessingModelParameter("KPH"))
m.addModelParameter(QgsProcessingParameterVectorLayer(
    "SUNGAI", "Layer sungai", [QgsProcessing.TypeVectorLine]), QgsProcessingModelParameter("SUNGAI"))
m.addModelParameter(QgsProcessingParameterNumber(
    "JARAK", "Lebar sempadan (m)", QgsProcessingParameterNumber.Double, 30),
    QgsProcessingModelParameter("JARAK"))


def anak(alat, deskripsi):
    c = QgsProcessingModelChildAlgorithm(alat)
    c.generateChildId(m)
    c.setDescription(deskripsi)
    return c


def dari_input(nama):
    return [Sumber.fromModelParameter(nama)]


def nilai(v):
    return [Sumber.fromStaticValue(v)]


def dari_anak(c, keluaran="OUTPUT"):
    return [Sumber.fromChildOutput(c.childId(), keluaran)]


# --- Penjaga: bila JARAK tidak lebih dari 0, model berhenti dengan pesan jelas
henti = anak("native:raiseexception", "Hentikan bila jarak tidak sah")
henti.addParameterSources("MESSAGE", nilai("Lebar sempadan harus lebih dari 0 meter."))
henti.addParameterSources("CONDITION", [Sumber.fromExpression("@JARAK <= 0")])
m.addChildAlgorithm(henti)

# --- Langkah utama: baru berjalan sesudah penjaga lolos
buf = anak("native:buffer", "Penyangga sungai")
buf.addParameterSources("INPUT", dari_input("SUNGAI"))
buf.addParameterSources("DISTANCE", dari_input("JARAK"))
buf.addParameterSources("DISSOLVE", nilai(True))
buf.setDependencies([QgsProcessingModelChildDependency(henti.childId())])
m.addChildAlgorithm(buf)

iris = anak("native:intersection", "Irisan dengan KPH")
iris.addParameterSources("INPUT", dari_input("KPH"))
iris.addParameterSources("OVERLAY", dari_anak(buf))
m.addChildAlgorithm(iris)

luas = anak("native:fieldcalculator", "Hitung luas (ha)")
luas.addParameterSources("INPUT", dari_anak(iris))
luas.addParameterSources("FIELD_NAME", nilai("LUAS_HA"))
luas.addParameterSources("FIELD_TYPE", nilai(0))
luas.addParameterSources("FIELD_LENGTH", nilai(10))
luas.addParameterSources("FIELD_PRECISION", nilai(2))
# rumus dihitung per fitur, jadi diberikan sebagai nilai tetap (teks)
luas.addParameterSources("FORMULA", nilai("round($area / 10000, 2)"))
keluaran = QgsProcessingModelOutput("SEMPADAN", "Sempadan per KPH")
keluaran.setChildOutputName("OUTPUT")
luas.setModelOutputs({"SEMPADAN": keluaran})
m.addChildAlgorithm(luas)

berkas = HASIL + "/Sempadan_Sungai_per_KPH.model3"
print("Model tersimpan?", m.toFile(berkas))
print("Langkah:", [c.description() for c in m.childAlgorithms().values()])
print("Masukan:", [p.name() for p in m.parameterDefinitions()])
