// Copyright (c) 2025, Your Company and contributors
// For license information, please see license.txt

frappe.ui.form.on("Declaration of value added tax", {
	il: function (frm) {
		fill_from_reports(frm);
	},
	ay: function (frm) {
		fill_from_reports(frm);
	},
});

// Pull the appendix tables from their source reports once both the year (İl)
// and month (Ay) are selected.
function fill_from_reports(frm) {
	if (!frm.doc.il || !frm.doc.ay) {
		return;
	}

	frappe.dom.freeze(__("Hesabatlardan doldurulur..."));
	frappe.call({
		method: "taxes_az.taxes_az.doctype.declaration_of_value_added_tax.declaration_of_value_added_tax.populate_vat_tables",
		args: { year: frm.doc.il, month: frm.doc.ay },
		callback: function (r) {
			frappe.dom.unfreeze();
			if (!r.message || !r.message.success) {
				frappe.msgprint(__("Doldurma alınmadı: {0}", [(r.message && r.message.error) || ""]));
				return;
			}

			set_table(frm, "əlavə_1", r.message.elave_1);
			set_table(frm, "əlavə_2", r.message.elave_2);
			set_table(frm, "əlavə_2_2", r.message.elave_2_2);
			set_table(frm, "əlavə1_yeni", r.message.elave_1_yeni);
			set_table(frm, "müəssisə_malın_dəyəri", r.message.elave_8_2);

			// Summary tables ship with their rows already created by a client
			// script, so fill them in place instead of rebuilding.
			fill_first_row(frm, "əlavə_1_2", r.message.elave_1_2);
			fill_rows_by_code(frm, "əlavə1_2_yeni", "sətirkodu", r.message.elave_1_2_yeni);

			frm.set_value(
				"sertifikathesabatdövründəmalındəyərininsəhifəsicəmi",
				r.message.elave_8_total
			);

			frm.refresh_fields();
			frappe.show_alert({ message: __("Əlavələr hesabatlardan dolduruldu"), indicator: "green" });
		},
	});
}

// Replace a child table's rows with the supplied data.
function set_table(frm, fieldname, rows) {
	frm.clear_table(fieldname);
	(rows || []).forEach(function (data) {
		const child = frm.add_child(fieldname);
		assign(child, data);
	});
	frm.refresh_field(fieldname);
}

// Fill the single summary row of a table without creating or deleting rows.
function fill_first_row(frm, fieldname, values) {
	const rows = frm.doc[fieldname] || [];
	if (!rows.length || !values) {
		return;
	}
	assign(rows[0], values);
	frm.refresh_field(fieldname);
}

// Fill pre-created summary rows, matching each row by the leading line code of
// `codefield`. The stored value carries a long description after the code, so
// only the first whitespace-delimited token is compared. Rows are never added
// or removed — a code with no data keeps the zeroed totals from the server.
function fill_rows_by_code(frm, fieldname, codefield, values_by_code) {
	const rows = frm.doc[fieldname] || [];
	if (!rows.length || !values_by_code) {
		return;
	}
	rows.forEach(function (row) {
		const code = String(row[codefield] || "").trim().split(/\s+/)[0];
		const values = values_by_code[code];
		if (values) {
			assign(row, values);
		}
	});
	frm.refresh_field(fieldname);
}

// Copy the supplied values onto a row, skipping keys the server left empty.
function assign(row, data) {
	Object.keys(data).forEach(function (key) {
		if (data[key] !== null && data[key] !== undefined) {
			row[key] = data[key];
		}
	});
}

// ===================================================================
// VAT column calculations (moved here from a Client Script so they live
// in version control, not the DB). Row creation stays in Client Scripts.
// ===================================================================
(function () {
// Verified ƏDV calculations (extracted from e-taxes bundle, live-verified).
// v2: adds roll-up behavior — parent = Σ children, and cross-table passthrough.

function vc_n(v) { return flt(v) || 0; }
function vc_r2(v) { return Math.round((v + (v >= 0 ? 1e-9 : -1e-9)) * 100) / 100; }
function vc_norm(s) { return String(s || "").trim().split(/\s+/)[0].replace(/\.+$/, ""); }
function vc_row(frm, table, code) {
    return (frm.doc[table] || []).find(function (r) { return vc_norm(r["göstəricilər"]) === code; });
}
// Parent (row whose code is a dot-prefix of others) = Σ its DIRECT dot-children, per column.
// Bottom-up. Dash rows (307-1, 303-1, 301-4 ...) are NOT dot-children, so they are excluded.
function vc_rollup(frm, table, cols) {
    var rows = frm.doc[table] || [];
    var kids = function (code) {
        var re = new RegExp("^" + code.replace(/[.\-]/g, "\\$&") + "\\.\\d+$");
        return rows.filter(function (r) { return re.test(vc_norm(r["göstəricilər"])); });
    };
    rows.slice().sort(function (a, b) {
        return vc_norm(b["göstəricilər"]).split(".").length - vc_norm(a["göstəricilər"]).split(".").length;
    }).forEach(function (r) {
        var ch = kids(vc_norm(r["göstəricilər"]));
        if (!ch.length) return; // leaf → keep user input
        cols.forEach(function (c) {
            var s = 0; ch.forEach(function (k) { s += vc_n(k[c]); });
            r[c] = vc_r2(s);
        });
    });
}

// --- turnover columns (Hesabat Dovriyye uzre) ---
var TCOST = "təqdimedilmişmalişvəxidmətlərindəyəriədvnəzərəalınmadan";
var TAMT = "daxilolmuşməbləğədvnəzərəalınmadan";
var TVAT = "ədvməbləği";
// --- appendix 4 / 5 columns (bare names, no ...ədvnəzərəalınmadan suffix!) ---
var A45COST = "təqdimedilmişmalişvəxidmətlərindəyəri";
var A45AMT = "daxilolmuşməbləğ";
// --- agro Hissə 1 amount column (fed into "purchased") ---
var A2H1AMT = "hesabatdövrüərzindəalınmışmallarınalışqiymətiiləməbləği";
// --- deductible / adjustments / settlements / debtor / agro columns ---
var DPAID = "ödənilmişməbləğədvnəzərəalınmadan";
var DVAT = "əlavədəyərvergisininməbləği";
var QPAID = "ödənilmişməbləğədvnəzərəalınmadan";
var QVAT = "əlavədəyərvergisiməbləği";
var SVAT = "ədvməbləği";
var BPREV = "hesabatdövrününəvvəlinədebitorborcməbləği";
var BINC = "hesabatdövrüayüzrəyaranandebitorborcməbləği";
var BREM = "hesabatdövrüayərzindəsilinəndebitorborcməbləği";
var BLAST = "hesabat_dövrünün_sonuna_debitor_borc_məbləği";
var ASTART = "hesabatdövrününəvvəlinəsatılmamışmallarınalışqiymətiiləməbləği";
var APUR = "dövrərzindəalınmışmallarınalışqiymətiiləməbləği";
var ASOLD = "dövrərzindəsatılmışmallarınsatışqiymətiiləməbləği";
var AEND = "dövrsonunamallarınalışqiymətiiləqalıqməbləği";
var AMARGIN = "carihesabatdövründəsatılmışmallaragörəticarətəlavəsi";
var AMVAT = "hesabatdövründəsatılmışmallaragörəticarətəlavəsininədvməbləği";

function vc_recompute(frm) {
    // ===== 1. Appendix internal roll-ups (parent = Σ dot-children) =====
    vc_rollup(frm, "əlavə_3_1", [TCOST, TAMT]);   // 301.1.1=Σ..., 301.1=Σ(301.1.x)
    vc_rollup(frm, "əlavə_4", [A45COST, A45AMT]);  // 302=Σ(302.x), 302.3=Σ(302.3.x)
    vc_rollup(frm, "əlavə_5", [A45COST, A45AMT]);  // 303=Σ(303.1..53), dash rows excluded

    // ===== 2. Agro (Appendix 2) — purchased = Σ Hissə 1, then margin =====
    var h1sum = 0;
    (frm.doc["əlavə_2"] || []).forEach(function (r) { h1sum += vc_n(r[A2H1AMT]); });
    (frm.doc["əlavə_2_2"] || []).forEach(function (row) {
        row[APUR] = vc_r2(h1sum);
        var cogs = vc_n(row[ASTART]) + h1sum - vc_n(row[AEND]);
        var margin = Math.max(0, vc_n(row[ASOLD]) - cogs);
        row[AMARGIN] = vc_r2(margin);
        row[AMVAT] = vc_r2(Math.max(0, margin * 18 / 100));
    });
    var agroSold = (frm.doc["əlavə_2_2"] || []).reduce(function (a, r) { return a + vc_n(r[ASOLD]); }, 0);
    frm.refresh_field("əlavə_2_2");

    // ===== 3. Passthrough: appendices → turnover =====
    var T = "hesabat_dövriyyəsi";
    var g = function (c) { return vc_row(frm, T, c); };
    var setv = function (c, f, val) { var r = g(c); if (r) r[f] = vc_r2(val); };
    var getv = function (c, f) { var r = g(c); return r ? vc_n(r[f]) : 0; };
    var pull = function (tcode, srcTable, scode, scost, samt) {
        var s = vc_row(frm, srcTable, scode);
        setv(tcode, TCOST, s ? vc_n(s[scost]) : 0);
        setv(tcode, TAMT, s ? vc_n(s[samt]) : 0);
    };
    pull("301.1", "əlavə_3_1", "301.1", TCOST, TAMT);   // 301.1 ← Əlavə 3
    pull("302", "əlavə_4", "302", A45COST, A45AMT);      // 302  ← Əlavə 4
    pull("303", "əlavə_5", "303", A45COST, A45AMT);      // 303  ← Əlavə 5
    setv("301-2", TCOST, agroSold);                      // 301-2 cost ← agro sold

    // ===== 4. Turnover formulas =====
    var a3_301_4 = vc_row(frm, "əlavə_3_1", "301-4");
    var term174 = a3_301_4 ? vc_n(a3_301_4[TAMT]) * 50 / 100 * 18 / 100 : 0;  // Art.174.5 50% relief
    setv("301.1", TVAT, getv("301.1", TAMT) * 18 / 100 - term174);
    setv("301.2", TVAT, Math.max(0, getv("301.2", TAMT) * 18 / 100));
    setv("304", TVAT, getv("304", TAMT) * 20 / 100);
    setv("306.1", TVAT, getv("306.1", TAMT) * 18 / 100);
    setv("306.2", TVAT, getv("306.2", TAMT) * 18 / 100);
    setv("306.3", TVAT, getv("306.3", TAMT) * 18 / 100);
    setv("301", TCOST, getv("301.1", TCOST));
    setv("301", TAMT, getv("301.1", TAMT) + getv("301.2", TAMT));
    setv("301", TVAT, getv("301.1", TVAT) + getv("301.2", TVAT));
    var cost305 = getv("301", TCOST) + getv("301-2", TCOST) + getv("302", TCOST) + getv("303", TCOST) + getv("304", TCOST);
    setv("305", TCOST, cost305);
    setv("302", TVAT, cost305 ? getv("302", TCOST) * 100 / cost305 : 0);   // %-share
    setv("303", TVAT, cost305 ? getv("303", TCOST) * 100 / cost305 : 0);   // %-share
    setv("305", TAMT, getv("301", TAMT) + getv("302", TAMT) + getv("303", TAMT) + getv("304", TAMT)); // 301-2 excluded
    setv("305", TVAT, getv("301", TVAT) + getv("304", TVAT));               // only 301 + 304
    setv("306", TCOST, getv("306.1", TCOST) + getv("306.1-1", TCOST));
    setv("306", TAMT, getv("306.1", TAMT) + getv("306.1-1", TAMT) + getv("306.2", TAMT) + getv("306.3", TAMT));
    setv("306", TVAT, getv("306.1", TVAT) + getv("306.2", TVAT) + getv("306.3", TVAT));
    frm.refresh_field(T);
    frm.refresh_field("əlavə_3_1"); frm.refresh_field("əlavə_4"); frm.refresh_field("əlavə_5");

    // ===== 5. Deductible VAT (308-317) =====
    var D = "əvəzləşdirilən_table";
    var gd = function (c, f) { var r = vc_row(frm, D, c); return r ? vc_n(r[f]) : 0; };
    var sd = function (c, f, val) { var r = vc_row(frm, D, c); if (r) r[f] = vc_r2(val); };
    sd("308.1", DVAT, gd("308.1", DPAID) * 18 / 100);
    sd("310.1", DVAT, gd("310.1", DPAID) * 18 / 100);
    sd("317", DVAT, Math.max(0, gd("308", DVAT) + gd("309", DVAT) + gd("310", DVAT) + gd("312", DVAT) - gd("313", DVAT) - gd("315", DVAT)));
    sd("317", DPAID, gd("308", DPAID) + gd("309", DPAID) + gd("310", DPAID) + gd("311", DPAID) + gd("312", DPAID) + gd("316", DPAID)); // 317 paidAmount total
    frm.refresh_field(D);

    // ===== 6. Adjustments (318/319) =====
    var Q = "dəqiqləşdirilən_table";
    var gq = function (c, f) { var r = vc_row(frm, Q, c); return r ? vc_n(r[f]) : 0; };
    var sq = function (c, f, val) { var r = vc_row(frm, Q, c); if (r) r[f] = vc_r2(val); };
    sq("318", QVAT, gq("318", QPAID) * 18 / 100);
    // 319.1-4 ƏDV = ödənilmiş məbləğ × dərəcə (fərqli — Art. 165.5/165.6 nağd/nağdsız qaytarma)
    sq("319.1", QVAT, gq("319.1", QPAID) * 18 / 100);
    sq("319.2", QVAT, gq("319.2", QPAID) * 17.1 / 100);
    sq("319.3", QVAT, gq("319.3", QPAID) * 14.85 / 100);
    sq("319.4", QVAT, gq("319.4", QPAID) * 12.6 / 100);
    sq("319", QVAT, gq("319.1", QVAT) + gq("319.2", QVAT) + gq("319.3", QVAT) + gq("319.4", QVAT));
    frm.refresh_field(Q);

    // ===== 7. Settlements (326/327) =====
    var net = getv("305", TVAT) + getv("306", TVAT) + gq("318", QVAT) + gq("324", QVAT)
        - gd("317", DVAT) - gq("319", QVAT) - gq("325", QVAT);
    var s326 = vc_row(frm, "hesablaşmalar_table", "326");
    var s327 = vc_row(frm, "hesablaşmalar_table", "327");
    if (s326) s326[SVAT] = vc_r2(Math.max(0, net));
    if (s327) s327[SVAT] = vc_r2(Math.max(0, -net));
    frm.refresh_field("hesablaşmalar_table");

    // ===== 8. Debtor debt (307): per-row roll-forward, then parent = Σ children =====
    (frm.doc["debitor_borc"] || []).forEach(function (row) {
        row[BLAST] = vc_r2(vc_n(row[BPREV]) + vc_n(row[BINC]) - vc_n(row[BREM]));
    });
    vc_rollup(frm, "debitor_borc", [BPREV, BINC, BREM, BLAST]);  // 307=Σ(307.x), 307-1=Σ(307-1.x)
    frm.refresh_field("debitor_borc");

    // ===== 9. Əlavə 1 cəmi (əlavə_1_2 = Σ əlavə_1) =====
    var e1a = 0, e1b = 0;
    (frm.doc["əlavə_1"] || []).forEach(function (r) {
        e1a += vc_n(r["ygbüzrəalınmışmalınədvsizdəyərimanatla"]);
        e1b += vc_n(r["ygbüzrəalınmışmalınədvməbləğimanatla"]);
    });
    (frm.doc["əlavə_1_2"] || []).forEach(function (row) {
        row["malınədvsizümumidəyəri"] = vc_r2(e1a);
        row["malınədvməbləği"] = vc_r2(e1b);
    });
    frm.refresh_field("əlavə_1_2");

    // ===== 10. Əlavə 1 (yeni) cəmi — totals per line code (308/314/316) =====
    var lead = function (s) { return String(s || "").trim().split(/\s+/)[0]; };
    var YC = ["ümumiməbləğmanatla", "ədvməbləğimanatla", "ödənilmişümumiməbləğmanatla", "ödənilmişədvməbləğimanatla"];
    (frm.doc["əlavə1_2_yeni"] || []).forEach(function (row) {
        var code = lead(row["sətirkodu"]);
        var acc = {}; YC.forEach(function (c) { acc[c] = 0; });
        (frm.doc["əlavə1_yeni"] || []).forEach(function (d) {
            if (lead(d["sətirkodu"]) === code) { YC.forEach(function (c) { acc[c] += vc_n(d[c]); }); }
        });
        YC.forEach(function (c) { row[c] = vc_r2(acc[c]); });
    });
    frm.refresh_field("əlavə1_2_yeni");

    // ===== 11. Əlavə 8 səhifə cəmi (parent field = Σ müəssisə_malın_dəyəri) =====
    var e8 = 0;
    (frm.doc["müəssisə_malın_dəyəri"] || []).forEach(function (r) {
        e8 += vc_n(r["sertifikataltındatəqdimolunanmallarınişlərinxidmətlərindəyəri"]);
    });
    frm.doc["sertifikathesabatdövründəmalındəyərininsəhifəsicəmi"] = vc_r2(e8);
    frm.refresh_field("sertifikathesabatdövründəmalındəyərininsəhifəsicəmi");
}

// --- Recompute exactly when the report-fill finishes — event-driven, no timer. Picking a
//     period fires populate_vat_tables + formula_editor (run_reports_batch) via frappe.call,
//     each writing many cells; recomputing per write would freeze the form. We wrap
//     frappe.call to track those specific calls: the per-write recompute is suppressed while
//     any is in flight, and runs ONCE when the last one resolves (deferred one tick so the
//     response's synchronous apply lands first). No timer, so it waits exactly as long as
//     the reports actually take. ---
var VC = (frappe.__vc = frappe.__vc || { mode: false, n: 0 });
VC.recompute = vc_recompute;                                  // always the current load's recompute
VC.re = /populate_vat_tables|run_reports_batch/;
if (!frappe.__vc_call_wrapped) {
    frappe.__vc_call_wrapped = true;
    var _vc_call = frappe.call;
    frappe.call = function (opts) {
        var m = (opts && opts.method) || (typeof opts === "string" ? opts : "");
        var fill = VC.re.test(m || "");
        var ret = _vc_call.apply(this, arguments);
        // Only enter fill mode if we can also observe completion — otherwise mode would
        // stick on forever and stop every recompute.
        if (fill && ret && typeof ret.then === "function") {
            VC.n++; VC.mode = true;
            var done = function () {
                if (--VC.n > 0) return;                        // other fill calls still running
                VC.n = 0;
                setTimeout(function () {                       // let this response's set_values apply first
                    VC.mode = false;
                    if (cur_frm && cur_frm.doctype === "Declaration of value added tax" && VC.recompute) {
                        VC.recompute(cur_frm);
                    }
                }, 0);
            };
            ret.then(done, done);
        }
        return ret;
    };
}
function vc_onchange(frm) {
    if (frappe.__vc.mode) return;   // report-fill running: recompute once when the last fill call resolves
    vc_recompute(frm);              // user edit: instant
}

// recompute on input changes in each child table
[
    ["Declaration of value added tax Elave 2 Hisse 1", [A2H1AMT]],
    ["Declaration of value added tax Elave 2 Hisse 2", [ASTART, ASOLD, AEND]],
    ["Declaration of value added tax Elave3 1ci", [TCOST, TAMT]],
    ["Declaration of value added tax Elave 4", [A45COST, A45AMT]],
    ["Declaration of value added tax Elave 5", [A45COST, A45AMT]],
    ["Declaration of value added tax Hesabat Dovriyye uzre", [TCOST, TAMT]],
    ["Declaration of value added tax Evezlesdirilen", [DPAID, DVAT]],
    ["Declaration of value added tax Deqiqlesdirilen", [QPAID, QVAT]],
    ["Declaration of value added tax Debitor borclar", [BPREV, BINC, BREM]],
    ["Declaration of value added tax Elave1 Cari hesabat", ["ygbüzrəalınmışmalınədvsizdəyərimanatla", "ygbüzrəalınmışmalınədvməbləğimanatla"]],
    ["Declaration of value added tax yeni elave 1", ["ümumiməbləğmanatla", "ədvməbləğimanatla", "ödənilmişümumiməbləğmanatla", "ödənilmişədvməbləğimanatla"]],
    ["Declaration of value added tax Elave 8 2ci", ["sertifikataltındatəqdimolunanmallarınişlərinxidmətlərindəyəri"]],
].forEach(function (pair) {
    var handlers = {};
    pair[1].forEach(function (fn) { handlers[fn] = function (frm) { vc_onchange(frm); }; });
    frappe.ui.form.on(pair[0], handlers);
});
})();
