// /AIWK_COMMON/site/aiwk_site_profile.js
// AIWK EXT4 v015
(function () {
    "use strict";

    const AIWK = window.AIWK;
    const profiles = {};

    function hostKey(host) {
        const h = String(host || "").trim().toLowerCase();
        if (!h) {
            throw new Error("SITE_PROFILE_HOST_EMPTY: host is required. 해결: 현재 페이지 hostname을 확인하십시오.");
        }
        return h.replace(/[^a-z0-9_.-]/g, "_");
    }

    function storageKey(host) {
        return "site_profile_" + hostKey(host);
    }

    function currentInfo() {
        return {
            href: String(location.href || ""),
            origin: String(location.origin || ""),
            host: String(location.host || ""),
            hostname: String(location.hostname || ""),
            pathname: String(location.pathname || "")
        };
    }

    function validateProfile(profile) {
        if (!profile || !profile.profile_id) {
            throw new Error("SITE_PROFILE_INVALID: profile_id is required. 해결: profile_id를 지정하십시오.");
        }
        if (!profile.site || !profile.site.domain) {
            throw new Error("SITE_PROFILE_INVALID: site.domain is required. 해결: site.domain을 지정하십시오.");
        }
        if (!profile.site.url_rules || !Array.isArray(profile.site.url_rules) || profile.site.url_rules.length < 1) {
            throw new Error("SITE_PROFILE_INVALID: site.url_rules is required. 해결: url_rules 배열을 지정하십시오.");
        }
        if (!profile.targets || typeof profile.targets !== "object") {
            throw new Error("SITE_PROFILE_INVALID: targets is required. 해결: 표준 target 정의를 지정하십시오.");
        }
        Object.keys(profile.targets).forEach(function (key) {
            const t = profile.targets[key];
            if (!t || !t.selector) {
                throw new Error("SITE_PROFILE_INVALID_TARGET: " + key + " selector is required. 해결: targets." + key + ".selector를 지정하십시오.");
            }
        });
        return true;
    }

    function buildDefaultForCurrentSite() {
        const info = currentInfo();
        const domain = info.hostname;
        if (!domain) {
            throw new Error("SITE_PROFILE_STOPPED: current hostname is empty. 해결: 일반 웹페이지에서 실행하십시오.");
        }
        return {
            profile_id: domain + ".default",
            version: "0.0.1",
            site: {
                domain: domain,
                url_rules: [info.origin + "/*"]
            },
            targets: {
                prompt_input: {
                    selector: "#prompt-textarea",
                    type: "input",
                    required: false,
                    note: "ChatGPT 계열 기본 예시. 사이트별로 수정하십시오."
                },
                send_button: {
                    selector: "button[data-testid='send-button']",
                    type: "button",
                    required: false,
                    note: "ChatGPT 계열 기본 예시. 사이트별로 수정하십시오."
                },
                answer_area: {
                    selector: "[data-message-author-role='assistant']",
                    type: "text",
                    required: false,
                    note: "응답 영역 기본 예시입니다."
                }
            },
            meta: {
                created_by: "local-dev",
                created_at: new Date().toISOString(),
                updated_at: new Date().toISOString(),
                source: "AIWK EXT4 v015 local test"
            }
        };
    }

    function save(profile) {
        if (!AIWK.auth.can("dev")) {
            throw new Error("DEV_ROLE_REQUIRED: site profile save requires dev. 해결: Token Login으로 dev 권한을 얻은 뒤 저장하십시오.");
        }
        validateProfile(profile);
        const copy = JSON.parse(JSON.stringify(profile));
        copy.meta = copy.meta || {};
        copy.meta.updated_at = new Date().toISOString();
        copy.meta.saved_by_role = AIWK.auth.role;
        copy.meta.saved_from = currentInfo().href;
        const key = storageKey(copy.site.domain);
        AIWK.store.set(key, copy);
        profiles[copy.profile_id] = copy;
        AIWK.events.emit("siteProfile:save", copy);
        return copy;
    }

    function loadForHost(host) {
        const profile = AIWK.store.get(storageKey(host), null);
        if (profile && profile.profile_id) {
            profiles[profile.profile_id] = profile;
        }
        return profile;
    }

    function removeForHost(host) {
        if (!AIWK.auth.can("dev")) {
            throw new Error("DEV_ROLE_REQUIRED: site profile remove requires dev. 해결: Token Login으로 dev 권한을 얻은 뒤 삭제하십시오.");
        }
        const profile = loadForHost(host);
        AIWK.store.remove(storageKey(host));
        if (profile && profile.profile_id) {
            delete profiles[profile.profile_id];
        }
        AIWK.events.emit("siteProfile:remove", { host: host, profile: profile || null });
        return profile || null;
    }

    function saveDefaultForCurrentSite() {
        return save(buildDefaultForCurrentSite());
    }

    function testRegisterCurrentSite() {
        const info = currentInfo();
        const saved = saveDefaultForCurrentSite();
        const loaded = loadForHost(info.hostname);
        if (!loaded || loaded.profile_id !== saved.profile_id) {
            throw new Error("SITE_PROFILE_SAVE_VERIFY_FAIL: 저장 후 같은 profile_id를 불러오지 못했습니다. 해결: AIWK.store와 host key를 확인하십시오.");
        }
        return {
            ok: 1,
            action: "site.profile.testRegisterCurrentSite",
            role: AIWK.auth.role,
            current: info,
            saved: saved,
            loaded: loaded,
            message: "site profile save/load verified"
        };
    }

    AIWK.siteProfile = {
        registry: profiles,
        currentInfo: currentInfo,
        buildDefaultForCurrentSite: buildDefaultForCurrentSite,
        validate: validateProfile,
        save: save,
        saveDefaultForCurrentSite: saveDefaultForCurrentSite,
        testRegisterCurrentSite: testRegisterCurrentSite,
        loadForHost: loadForHost,
        removeForHost: removeForHost,
        storageKey: storageKey,
        list: function () {
            const out = [];
            Object.keys(profiles).forEach(function (id) {
                out.push(profiles[id]);
            });
            return out;
        }
    };
}());
