import { expect } from '@jest/globals';
import { render } from '@testing-library/react';

import type { RenderResult } from '@testing-library/react';

import FormattedText from './FormattedText';

describe('FromattedText', () => {
  describe('default', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music with a lot of melodies."
        />
      );
    });

    it('has one <p>', () => {
      expect(component.container.querySelectorAll('p')).toHaveLength(1);
    });
  });

  describe('w/ http link', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music with a lot of melodies. Visit http://example.com"
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('http://example.com/');
      expect(els[0].textContent).toBe('http://example.com');
    });
  });

  describe('w/ https link', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music with a lot of melodies. Visit https://example.com"
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('https://example.com/');
      expect(els[0].textContent).toBe('https://example.com');
    });
  });

  describe('w/ url w/ upper-case chars', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music with a lot of melodies. Visit https://vm.tiktok.com/ZMJHJQ5m5."
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('https://vm.tiktok.com/ZMJHJQ5m5');
      expect(els[0].textContent).toBe('https://vm.tiktok.com/ZMJHJQ5m5');
    });
  });

  describe('w/ url w/ @', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music with a lot of melodies. Visit https://tiktok.com/@wilsonpage."
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('https://tiktok.com/@wilsonpage');
      expect(els[0].textContent).toBe('https://tiktok.com/@wilsonpage');
    });
  });

  describe('w/ email', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text="I mostly make music wilson@songwhip.com with a lot of melodies."
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('mailto:wilson@songwhip.com');
      expect(els[0].textContent).toBe('wilson@songwhip.com');
    });
  });

  describe('w/ odd', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text={`I mostly make music with a lot of melodies. Cheerful electronic but sometimes other genres.

I play on a keyboard and on acoustic guitar. Improvisations and remixes are mostly on youtube.

I like reading and black tea.

If you want to donate something directly:
bc1qru2dauv4ha5p9cqrzekxax9ngrzpw7n6ky725x

Persona avatar by Aspid:
www.deviantart.com/aspidart`}
        />
      );
    });

    it('has expected <a> tags', () => {
      const els = component.container.querySelectorAll('a');

      expect(els).toHaveLength(1);
      expect(els[0].href).toBe('http://www.deviantart.com/aspidart');
      expect(els[0].textContent).toBe('www.deviantart.com/aspidart');
    });
  });

  describe('as lyrics', () => {
    let component: RenderResult;

    beforeEach(() => {
      component = render(
        <FormattedText
          size={14}
          lineHeight="16px"
          withLinkify
          text={`
I saw a light right beside me
An angel on a star
Can you teach how to love?

You feel the demons inside me
While I wonder how you are
If you hear me from above

Why don't you fall in love?
I wondered for so long
What are you looking for?
I guess I'll never know
Because today I wonder
If I did something wrong
If I broke someone's heart


God only knows how I'm missing
The feeling when you fall
Fall in someone's arms

I look in my eyes and I wonder
If I'll ever see you again
If I'll hold you back again

Why don't you fall in love?
I wondered for so long
What are you looking for?
I guess I'll never know
Because today I wonder
If I did something wrong
If I broke someone's heart

Why don't you fall in love?
I wondered for so long
What are you looking for?
I guess I'll never know
Because today I wonder
If I did something wrong
If I broke someone's heart


`}
        >
          <span />
        </FormattedText>
      );
    });

    it('has expected <br> tags', () => {
      const els = component.container.querySelectorAll('br');

      expect(els).toHaveLength(38);
    });

    it('inserts the overflow span in the last <p>', () => {
      const p = component.container.querySelector('p');
      const span = p!.querySelector('span');

      const childNodes = p!.childNodes;
      const lastChildNode = childNodes[childNodes.length - 1];

      expect(lastChildNode).toBe(span);
      expect(p!.querySelectorAll('span')).toHaveLength(1);
    });
  });
});
