// @vitest-environment jsdom
import { describe, it, expect, vi } from 'vitest';
import { supportsFieldSizing, autosizeTextarea } from './composerAutosize';

/**
 * scrollHeight を style.height に依存するゲッターで返す。
 * 実ブラウザと同じく、height が明示設定されていたら見えている箱の高さ以上の値を返す。
 * height が auto または未設定なら、コンテンツ実寸（contentPx）を返す。
 * これにより「height を auto に戻さない実装」を検出できる。
 */
function textareaWithContentHeight(contentPx: number): HTMLTextAreaElement {
  const el = document.createElement('textarea');
  Object.defineProperty(el, 'scrollHeight', {
    configurable: true,
    get() {
      const h = parseInt(this.style.height, 10);
      // height:auto または未設定なら、実コンテンツ高さを返す
      if (this.style.height === 'auto' || Number.isNaN(h)) return contentPx;
      // 明示 height が付いたままなら、その値以上を返す
      return Math.max(h, contentPx);
    },
  });
  return el;
}

/**
 * レガシーヘルパー。静的 scrollHeight を使う拡張テストで利用。
 */
function textareaWithScrollHeight(h: number): HTMLTextAreaElement {
  const el = document.createElement('textarea');
  Object.defineProperty(el, 'scrollHeight', { value: h, configurable: true });
  return el;
}

describe('supportsFieldSizing', () => {
  it('jsdom (CSS.supports 非対応環境) では false', () => {
    // jsdom の CSS.supports は field-sizing を知らない → フォールバック経路に入る
    expect(supportsFieldSizing()).toBe(false);
  });

  it('CSS グローバルが無い環境でも throw せず false', () => {
    vi.stubGlobal('CSS', undefined);
    try {
      expect(supportsFieldSizing()).toBe(false);
    } finally {
      vi.unstubAllGlobals();
    }
  });
});

describe('autosizeTextarea', () => {
  it('scrollHeight まで高さを伸ばす（max 以内）', () => {
    const el = textareaWithScrollHeight(120);
    autosizeTextarea(el, 192);
    expect(el.style.height).toBe('120px');
    expect(el.style.overflowY).toBe('hidden');
  });

  it('max を超えたら max で止めて縦スクロールにする', () => {
    const el = textareaWithScrollHeight(500);
    autosizeTextarea(el, 192);
    expect(el.style.height).toBe('192px');
    expect(el.style.overflowY).toBe('auto');
  });

  it('縮小方向にも効く（height を一度 auto に戻してから測る）', () => {
    const el = textareaWithContentHeight(60);
    el.style.height = '192px';
    autosizeTextarea(el, 192);
    // height を auto に戻して初めてコンテンツ実寸 60px を測れる。
    // もし height を auto に戻さない実装なら、scrollHeight は 192px 以上を返して 192px で止まる。
    expect(el.style.height).toBe('60px');
  });
});
