import { SwcUtils } from '../../utils/Utils';
import { SwcAppInterface } from '../SwcAppInterface';
import { SwcHTMLElementInterface } from '../SwcHTMLElementInterface';

export abstract class SwcHTMLImageElementBase extends HTMLImageElement implements SwcHTMLElementInterface {
  protected _masterTplNodes: Node[] = [];
  protected _asKey: string = 'value';
  protected _asIndexKey: string = 'index';

  constructor() {
    super();
  }

  public getNearAppHost(): SwcAppInterface | undefined {
    const hosts = this.getHosts();
    // [Root, ..., Parent] 순서이므로 reverse() 후 find 하여 최측근을 찾습니다.
    return hosts.reverse().find(host => host.tagName.toLowerCase() === 'swc-app' || host.getAttribute('is')?.startsWith('swc-app-')) as SwcAppInterface | undefined;
  }

  public getHosts(): SwcHTMLElementInterface[] {
    return SwcUtils.findAllSwcHosts(this as any);
  }

  public getHost(): SwcHTMLElementInterface | undefined {
    const hosts = this.getHosts();
    return hosts.length > 0 ? hosts[hosts.length - 1] : undefined;
  }

  public getFirstHost(): SwcHTMLElementInterface | undefined {
    const hosts = this.getHosts();
    return hosts.length > 0 ? hosts[0] : undefined;
  }

  public getLastHost(): SwcHTMLElementInterface | undefined {
    return this.getHost();
  }

  protected initCore() {
    this._asKey = this.getAttribute('as') || 'value';
    this._asIndexKey = this.getAttribute('as-index') || 'index';

    if (this._masterTplNodes.length > 0) return; // 이미 초기화됨

    const tplSlot = this.shadowRoot?.getElementById('tpl-slot') as HTMLSlotElement;
    if (tplSlot) {
      this._masterTplNodes = tplSlot.assignedNodes().map(n => n.cloneNode(true));
    } else if (this.childNodes.length > 0) {
      // Light DOM에서 템플릿 추출
      this._masterTplNodes = Array.from(this.childNodes).map(n => n.cloneNode(true));
    }
  }

  protected applyData(node: Node, data: any, index?: number) {
    // 호스트 체인에서 name→value 컨텍스트 수집
    const hostContext: Record<string, any> = {};
    let curr: any = (this as any).parentElement || ((this as any).getRootNode?.() as any)?.host;
    const hostChain: any[] = [];
    while (curr) {
      if (typeof curr._getHostContext === 'function') hostChain.unshift(curr);
      curr = curr.parentElement || (curr.getRootNode?.() as any)?.host;
    }
    for (const h of hostChain) {
      Object.assign(hostContext, h._getHostContext());
    }

    SwcUtils.applyData(node, data, {
      asKey: this._asKey,
      asIndexKey: this._asIndexKey,
      index,
      hostContext
    });
  }

  protected createReactiveProxy(target: any, onChange: () => void, onIndexChange?: (index: number, val: any) => void) {
    return SwcUtils.createReactiveProxy(target, onChange, onIndexChange);
  }
}
