(function exposeStateStore(global) {
  "use strict";

  function create(domains) {
    const owners = new Map();
    const stores = {};
    Object.entries(domains).forEach(([domain, values]) => {
      stores[domain] = { ...values };
      Object.keys(values).forEach((key) => {
        if (owners.has(key)) throw new Error(`Duplicate state field: ${key}`);
        owners.set(key, domain);
      });
    });

    const proxy = new Proxy({}, {
      get(_target, key) {
        if (key === "domain") return (name) => stores[name];
        if (key === "domains") return Object.freeze({ ...stores });
        if (typeof key !== "string" || !owners.has(key)) return undefined;
        return stores[owners.get(key)][key];
      },
      set(_target, key, value) {
        if (typeof key !== "string" || !owners.has(key)) {
          throw new Error(`Unregistered application state field: ${String(key)}`);
        }
        stores[owners.get(key)][key] = value;
        return true;
      },
      has(_target, key) {
        return key === "domain" || key === "domains" || owners.has(key);
      },
      ownKeys() {
        return [...owners.keys()];
      },
      getOwnPropertyDescriptor(_target, key) {
        if (!owners.has(key)) return undefined;
        return { enumerable: true, configurable: true };
      },
    });
    return proxy;
  }

  global.XiaobaiState = Object.freeze({ create });
})(window);
