/**
 * Lightweight @testing-library/react-native mock for Vitest.
 * Uses react-test-renderer under the hood with simple query helpers.
 */
import React from 'react';
import renderer, { type ReactTestRendererJSON } from 'react-test-renderer';

function collectTexts(node: ReactTestRendererJSON | ReactTestRendererJSON[] | string | null): string[] {
  if (node === null) return [];
  if (typeof node === 'string') return [node];
  if (Array.isArray(node)) return node.flatMap(collectTexts);

  const texts: string[] = [];
  if (node.children) {
    for (const child of node.children) {
      texts.push(...collectTexts(child));
    }
  }
  return texts;
}

function collectNodes(node: ReactTestRendererJSON | ReactTestRendererJSON[] | null): ReactTestRendererJSON[] {
  if (node === null) return [];
  if (Array.isArray(node)) return node.flatMap(collectNodes);

  const nodes: ReactTestRendererJSON[] = [node];
  if (node.children) {
    for (const child of node.children) {
      if (typeof child !== 'string') {
        nodes.push(...collectNodes(child));
      }
    }
  }
  return nodes;
}

let currentTree: ReturnType<typeof renderer.create> | null = null;

export function render(element: React.ReactElement) {
  currentTree = renderer.create(element);
  return { unmount: () => currentTree?.unmount() };
}

export const screen = {
  getByText(text: string) {
    const json = currentTree?.toJSON();
    const allTexts = collectTexts(json ?? null);
    const found = allTexts.find((t) => t.includes(text));
    if (!found) throw new Error(`Unable to find text: "${text}"`);
    return { type: 'Text', children: [found] };
  },

  getByPlaceholderText(placeholder: string) {
    const json = currentTree?.toJSON();
    const allNodes = collectNodes(json ?? null);
    const found = allNodes.find(
      (n) => n.props?.placeholder === placeholder || n.props?.placeholderTextColor != null && n.props?.placeholder === placeholder,
    );
    if (!found) throw new Error(`Unable to find placeholder: "${placeholder}"`);
    return found;
  },

  queryByText(text: string) {
    try {
      return screen.getByText(text);
    } catch {
      return null;
    }
  },
};

export function fireEvent(element: ReactTestRendererJSON, event: string, ...args: unknown[]) {
  const handler = element.props?.[`on${event.charAt(0).toUpperCase()}${event.slice(1)}`];
  if (typeof handler === 'function') handler(...args);
}

fireEvent.press = (element: ReactTestRendererJSON) => fireEvent(element, 'press');
fireEvent.changeText = (element: ReactTestRendererJSON, text: string) => fireEvent(element, 'changeText', text);
