import { attribute, elementDefine, innerHtml, onAttributeChanged } from '../index';
import { SwcHTMLCanvasElementBase } from '../elements/base/SwcHTMLCanvasElementBase';

@elementDefine({ name: 'swc-for-of-canvas', extends: 'canvas' })
export class SwcForOfCanvas extends SwcHTMLCanvasElementBase {
  private _placeholder = document.createComment("swc-for-of-placeholder");
  private _isShowing = true; private _isConnected = false;
  @attribute('swc-value') _swcValue: any[] = [];
  private _rowNodes: Node[][] = [];
  @onAttributeChanged('swc-value') onValueChange() { if (!Array.isArray(this._swcValue)) this._swcValue = []; if (!(this._swcValue as any).__swc_is_proxy) { this._swcValue = this.createReactiveProxy(this._swcValue, () => this.renderAll(), (idx, v) => this.updateSingleRow(idx, v)); } if (this._isConnected) { if (this._masterTplNodes.length === 0) this.initCore(); this.evaluate(); } }
  set swcValue(val: any[]) { this._swcValue = val; } get swcValue(): any[] { return this._swcValue; }
  @innerHtml renderTemplate() { return `<slot id="tpl-slot" style="display:none;"></slot>`; }
  connectedCallback() { this._isConnected = true; this.initCore(); this.evaluate(); }
  private evaluate() { if (this._masterTplNodes.length === 0) this.initCore(); const hasData = Array.isArray(this._swcValue) && this._swcValue.length > 0; if (!hasData && this._isShowing) { if (this.parentNode) { this.parentNode.insertBefore(this._placeholder, this); this.remove(); this._isShowing = false; } } else if (hasData) { if (!this._isShowing) { if (this._placeholder.parentNode) { this._placeholder.parentNode.insertBefore(this, this._placeholder); this._placeholder.remove(); this._isShowing = true; } } this.renderAll(); } }
  public updateSingleRow(index: number, newValue: any) { if (!this._isShowing) return; const nodes = this._rowNodes[index]; if (nodes && nodes.length > 0) { nodes.forEach(node => this.applyData(node, newValue, index)); } else { this.renderRow(newValue, index); } }
  public addRow(item: any) { this._swcValue.push(item); }
  public removeRow(index: number) { if (index < 0 || index >= this._rowNodes.length) return; this._rowNodes[index].forEach(node => (node as Element).remove()); this._rowNodes.splice(index, 1); this._swcValue.splice(index, 1); for (let i = index; i < this._rowNodes.length; i++) { this._rowNodes[i].forEach(node => this.applyData(node, this._swcValue[i], i)); } this.evaluate(); }
  private renderRow(item: any, index: number) { if (this._masterTplNodes.length === 0) return; const currentNodes: Node[] = []; this._masterTplNodes.forEach(tplNode => { const clone = tplNode.cloneNode(true); this.appendChild(clone); this.applyData(clone, item, index); currentNodes.push(clone); }); this._rowNodes[index] = currentNodes; }
  private renderAll() { this.innerHTML = ''; this._rowNodes = []; this._swcValue.forEach((item, index) => this.renderRow(item, index)); }
}
