/// <reference types="cypress" />

import makeFakeSession from '../../factories/session';
import makeFakeUser from '../../factories/user';
import { faker } from '@faker-js/faker';

describe('Browse sessions', () => {
  const currentUser = makeFakeUser();
  beforeEach(() => {
    cy.stubAuthenticate({ id: currentUser.id });
  });

  describe('when there are no active sessions', () => {
    beforeEach(() => {
      cy.intercept('GET', /\S+\/api\/sessions/, {
        body: []
      });
      cy.visit('/sessions');
    });

    it('alerts when there is no records', () => {
      cy.contains('There are no public, open sessions currently available for you to join');
      cy.contains('create a session').click();
      cy.url().should('include', '/sessions/new');
    });
  });

  describe('when there are active sessions', () => {
    describe('in desktop', () => {
      beforeEach(() => {
        cy.viewport('macbook-15');
      });

      it('lists the sessions', () => {
        const session = makeFakeSession({
          participants: [
            {
              user: {
                name: 'John Doe'
              },
              tracks: [
                {
                  id: '1',
                  instrument: 'Guitar'
                }
              ]
            },
            {
              user: {
                name: 'Ray Charles'
              },
              tracks: [
                {
                  id: '2',
                  instrument: 'Bass'
                }
              ]
            }
          ]
        }); 
        cy.intercept('GET', /\S+\/api\/sessions/, [session]);
        cy.visit('/sessions');
        cy.get('[data-testid=sessionsListTable] tbody tr').should('have.length', 1);
      });

      describe('session description', () => {
        it('when user has provided a description', () => {
          const session = makeFakeSession({
            description: 'custom description',
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('custom description');
        });

        it('when user has not provided a description and session is public', () => {
          const session = makeFakeSession({
            description: null,
            musician_access: true,
            approval_required: false,
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('Public, open session. Feel free to join!');
        });

        it('when user has not provided a description and session is private and requires approval to join', () => {
          const session = makeFakeSession({
            description: null,
            musician_access: true,
            approval_required: true,
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains(
            'Private session. Click the enter button in the right column to request to join'
          );
        });

        it('when user has not provided a description and session is RSVP', () => {
          const session = makeFakeSession({
            description: null,
            musician_access: false,
            approval_required: false,
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('Only RSVP musicians may join');
        });
      });

      describe('invitation', () => {
        it('shows invite detail if the user has been invited', () => {
          const session = makeFakeSession({
            invitations: [
              {
                sender_id: '1',
                receiver_id: currentUser.id
              }
            ],
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('YOU WERE INVITED TO THIS SESSION');
        });
      });

      describe('friend info', () => {
        it('shows if there is a friend in session', () => {
          const session = makeFakeSession({
            participants: [
              {
                user: {
                  is_friend: true,
                  name: faker.person.fullName()
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              }
            ]
          });
          //console.log('_DEBUG_ session', session);
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('YOU HAVE A FRIEND IN THIS SESSION');
        });
      });

      describe('participants', () => {
        it('shows the participants', () => {
          const session = makeFakeSession({
            participants: [
              {
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              },
              {
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('John Doe');
          cy.get('[data-testid=sessionsListTable] tbody tr').contains('Ray Charles');
        });
      });

      describe('instruments', () => {
        it('shows the instruments', () => {
          const session = makeFakeSession({
            participants: [
              {
                id: 'p1',
                user: {
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Electric Guitar',
                    instrument_id: 'electric_guitar'
                  },
                  {
                    id: '2',
                    instrument: 'Drums',
                    instrument_id: 'drums'
                  }
                ]
              },
              {
                id: 'p2',
                user: {
                  name: 'Ray Charles'
                },
                tracks: [
                  {
                    id: '2',
                    instrument: 'Bass Guitar',
                    instrument_id: 'bass_guitar'
                  }
                ]
              }
            ]
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr')
            .find(`[data-testid=Participantp1Tracks]`).trigger('mouseover')
          //cy.contains('Electric Guitar');
          // cy.get('[data-testid=sessionsListTable] tbody tr')
          //   .find(`[data-testid=Participantp1Tracks]`)
          //   .contains('Drums');
          // cy.get('[data-testid=sessionsListTable] tbody tr')
          //   .find(`[data-testid=Participantp2Tracks]`)
          //   .contains('Bass');
        });
      });

      describe('click join button - on a private session', () => {
        it('shows toast message', () => {
          const session = makeFakeSession({
            participants: [
              {
                user: {
                  id: '1',
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              }
            ],
            musician_access: true,
            approval_required: true
          });
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.intercept('GET', /\S+\/api\/users\/\S+\/latencies\?\S+/, { users: [{
            user_id: currentUser.id,
            first_name:"John",
            last_name:"Doe",
            audio_latency:5,
            audio_latency_unknown:false,
          }]});

          cy.visit('/sessions');
          cy.get('[data-testid=sessionsListTable] tbody tr')
            .find('[data-testid=joinBtn]')
            .click();
          cy.contains('You have requested to join this private session.');
          // cy.get('[data-testid=native-app-unavailable]').contains('Cancel').click();
        });
      });

      describe('click join button - on a public session', () => {
        it('opens native client', () => {
          const session = makeFakeSession({
            participants: [
              {
                user: {
                  id: '1',
                  name: 'John Doe'
                },
                tracks: [
                  {
                    id: '1',
                    instrument: 'Guitar'
                  }
                ]
              }
            ], 
            musician_access: true,
            approval_required: false
          });
          const newUrl = `jamkazam://url=http://www.jamkazam.local:3000/client#/findSession/custom~yes%7CjoinSessionId~${
            session.id
          }`;
          cy.intercept('GET', /\S+\/api\/sessions/, [session]);
          cy.intercept('GET', /\S+\/api\/users\/\S+\/latencies\?\S+/, { users: [{
            user_id: currentUser.id,
            first_name:"John",
            last_name:"Doe",
            audio_latency:5,
            audio_latency_unknown:false,
          }]});
          cy.visit('/sessions').then(win => {
            cy.stub(win, 'open').as('windowOpen');
          });
          // cy.get('[data-testid=sessionsListTable] tbody tr')
          //   .find('[data-testid=joinBtn]')
          //   .click();
          //cy.get('@windowOpen').should('have.been.calledWith', newUrl);
        });
      });
    });

    describe.skip('in mobile', () => {
      beforeEach(() => {
        cy.viewport('iphone-6');
      });

      describe('pagination', () => {
        it('shows the next page of sessions', () => {
          const sessions = [];
          for (let i = 0; i < 5; i++) {
            sessions.push(makeFakeSession({ id: faker.string.uuid() }));
          }
          cy.intercept('GET', /\S+\/api\/sessions/, sessions);
          cy.visit('/sessions');
          cy.get('[data-testid=sessionsSwiper] .swiper-button-prev').should('have.class', 'swiper-button-disabled');
          for (let i = 0; i < 4; i++) {
            // 4 because the first one is already visible
            cy.get('[data-testid=sessionsSwiper] .swiper-button-next').click();
            cy.wait(500);
          }
          cy.get('[data-testid=sessionsSwiper] .swiper-button-next').should('have.class', 'swiper-button-disabled');
        });
      });
    });
  });
});
