<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Vue from Scratch</title>
</head>

<body>
    <script>
        function reactive(obj) {
            const listeners = new Set();

            const proxy = new Proxy(obj, {
                get(target, property, receiver) {
                    if (typeof target[property] === 'object' && target[property] !== null) {
                        return reactive(target[property]);
                    }
                    return Reflect.get(target, property, receiver);
                },
                set(target, property, value, receiver) {
                    const result = Reflect.set(target, property, value, receiver);
                    listeners.forEach(fn => fn());
                    return result;
                }
            });

            proxy.subscribe = function (fn) {
                listeners.add(fn);
            };

            proxy.unsubscribe = function (fn) {
                listeners.delete(fn);
            };

            return proxy;
        }

        class Component {
            constructor(options) {
                this.template = options.template;
                this.data = reactive(options.data());
                this.methods = options.methods;
                this.style = options.style;
                this.rootId = options.rootId;

                // Ensure root element exists
                if (!document.getElementById(this.rootId)) {
                    const rootElement = document.createElement('div');
                    rootElement.id = this.rootId;
                    document.body.appendChild(rootElement);
                }

                this.data.subscribe(this.render.bind(this));
                this.render();
            }

            compileTemplate(template) {
                const match = template.match(/{{\s*(\w+)\s*}}/g);
                return () => {
                    let compiledTemplate = template;
                    if (match) {
                        match.forEach(item => {
                            const key = item.replace(/{{\s*|\s*}}/g, '');
                            compiledTemplate = compiledTemplate.replace(item, this.data[key]);
                        });
                    }
                    return compiledTemplate;
                };
            }

            render() {
                const el = document.getElementById(this.rootId);
                if (el) {
                    el.innerHTML = this.compileTemplate(this.template)();
                    this.applyMethods(el);
                }
            }

            applyMethods(el) {
                Object.keys(this.methods).forEach(methodName => {
                    const matches = el.querySelectorAll(`[data-action="${methodName}"]`);
                    matches.forEach(match => {
                        match.onclick = this.methods[methodName].bind(this.data);
                    });
                });
            }
        }

        const MyComponent = new Component({
            template: `
          <div class="my-component">
            <div class="container">
              <p class="message">Count: {{ count }}</p>
              <div class="buttons">
                <button data-action="increment">Increment</button>
                <button data-action="decrement">Decrease</button>
              </div>
            </div>
          </div>
        `,
            data() {
                return {
                    count: 0,
                };
            },
            methods: {
                increment() {
                    this.count += 1;
                },
                decrement() {
                    this.count -= 1;
                },
            },
            style: `
          .my-component {
            font-family: Arial, sans-serif;
            text-align: center;
            padding: 50px;
            background: #f0f0f0;
          }
          .my-component .container {
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
          }
          .my-component .message {
            font-size: 24px;
            margin-bottom: 20px;
          }
          .my-component .buttons button {
            font-size: 16px;
            padding: 10px 20px;
            margin: 5px;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            transition: background 0.3s;
          }
          .my-component .buttons button:hover {
            background: #ddd;
          }
          .my-component .buttons button:active {
            background: #ccc;
          }
        `,
            rootId: 'root' // Specify the ID for the root element
        });

        // Ensure CSS is applied to the component
        const style = document.createElement('style');
        style.textContent = MyComponent.style;
        document.head.appendChild(style);
    </script>
</body>

</html>