// @ts-check
import React from 'react';
import { test, expect } from '@playwright/experimental-ct-react';
import Input from './index.jsx';
import { axeptio } from '../../../Presets';
import { Provider } from '../../../DesignSystem';

/**
 * Custom test utility function that wraps a test component with ThemeProvider
 * This function cannot be imported from another file because it breaks the tests
 * https://github.com/microsoft/playwright/issues/15620
 * @param {JSX.Element} component
 */
function withThemeProvider(component) {
  return (
    /* @ts-expect-error Server Component */
    <Provider theme={axeptio}>{component}</Provider>
  );
}

test.use({ viewport: { width: 500, height: 500 } });

test('Input enable', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  await expect(component).toBeEnabled();
});

test('Font Family', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  await expect(component.locator('label')).toHaveCSS('font-family', '"Source Sans Pro", sans-serif');
});

test('Max Width', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  await expect(component.locator('label')).toHaveCSS('max-width', '400px');
});

test('Special Width', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input width={200} type="email" label="Email" onChange={undefined} />));
  await expect(component.locator('label')).toHaveCSS('width', '200px');
});

test('Disable', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input disabled type="email" label="Email" onChange={undefined} />));
  await expect(component.locator('input')).toBeDisabled();
});

test('Editable', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  await expect(component.locator('input')).toBeEditable();
});

test('Label', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  await expect(component).toContainText('Email');
});

test('Focus', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  const input = component.locator('input');
  await input.focus();
  await expect(input).toBeFocused();
});

test('Border color on focus', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" onChange={undefined} />));
  const input = component.locator('input');
  await input.focus();
  await expect(input).toHaveCSS('border-color', 'rgba(0, 0, 0, 0) rgb(33, 33, 33) rgb(33, 33, 33)');
});

test('Typing', async ({ mount }) => {
  let content = null;
  const component = await mount(
    withThemeProvider(
      <Input
        type="email"
        label="Email"
        onChange={val => {
          content = val;
        }}
      />
    )
  );
  await component.locator('input').type('Hello');
  await expect(content === 'Hello').toBeTruthy();
});

test('With value', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" label="Email" value={'Hello'} onChange={undefined} />));
  await expect(component.locator('input')).toHaveValue('Hello');
});

test('Error value color', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input error={'Wrong Email'} type="email" label="Email" onChange={undefined} />)
  );
  const error = component.locator('div.footer');
  await expect(error).toHaveCSS('color', 'rgb(226, 47, 90)');
});

test('Error value text', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input error={'Wrong Email'} type="email" label="Email" onChange={undefined} />)
  );
  const error = component.locator('div.footer');
  await expect(error).toContainText('Wrong Email');
});

test('Error margin text', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input error={'Wrong Email'} type="email" label="Email" onChange={undefined} />)
  );
  const error = component.locator('div.footer');
  await expect(error).toHaveCSS('margin-top', '5px');
});

test('Input unit value', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input unit={'px'} type="number" label="size" onChange={undefined} />));
  const error = component.locator('span.InputUnit');
  await expect(error).toContainText('px');
});

test('Input unit value error', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input unit={'px'} error={'Wrong value'} type="number" label="size" onChange={undefined} />)
  );
  const error = component.locator('span.InputUnit');
  await expect(error).toHaveCSS('color', 'rgb(226, 47, 90)');
});

test('Input unit border color', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input unit={'px'} error={'Wrong value'} type="number" label="size" onChange={undefined} />)
  );
  const input = component.locator('input');
  await input.focus();
  const error = component.locator('span.InputUnit');
  await expect(error).toHaveCSS('border-left', '0px none rgba(0, 0, 0, 0)');
  await expect(error).toHaveCSS('border-right', '2px solid rgb(33, 33, 33)');
  await expect(error).toHaveCSS('border-top', '2px solid rgb(33, 33, 33)');
  await expect(error).toHaveCSS('border-bottom', '2px solid rgb(33, 33, 33)');
  await expect(error).toHaveCSS('color', 'rgb(33, 33, 33)');
});

test('Input unit border color error', async ({ mount }) => {
  const component = await mount(
    withThemeProvider(<Input unit={'px'} error={'Wrong value'} type="number" label="size" onChange={undefined} />)
  );
  const error = component.locator('span.InputUnit');
  await expect(error).toHaveCSS('border-left', '0px none rgb(226, 47, 90)');
  await expect(error).toHaveCSS('border-right', '2px solid rgb(226, 47, 90)');
  await expect(error).toHaveCSS('border-top', '2px solid rgb(226, 47, 90)');
  await expect(error).toHaveCSS('border-bottom', '2px solid rgb(226, 47, 90)');
  await expect(error).toHaveCSS('color', 'rgb(226, 47, 90)');
});

test('Textarea enable', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" multiline label="Email" onChange={undefined} />));
  await expect(component.locator('textarea')).toBeEnabled();
});

test('Textarea editable', async ({ mount }) => {
  const component = await mount(withThemeProvider(<Input type="email" multiline label="Email" onChange={undefined} />));
  await expect(component.locator('textarea')).toBeEditable();
});
