import { syncFetch } from '../util';
import * as gtm from './gtm';
import Selector = JQuery.Selector;
import Chainable = Cypress.Chainable;

function withPreviousUrl(callback: (url: string) => unknown): void {
   cy.url().then((url) => {
      callback(url);

      if (url.startsWith('about:')) {
         url = '/';
      }

      cy.visit(url);
   });
}

export const testUser = {
   email: 'cuchac@email.cz',
   password: 'wpjwpj123',
   name: 'Wpj',
   surname: 'Wpj',
   phone: '+420728123219',
   street: 'Fügnerova 1288',
   city: 'Vrchlabí',
   zip: '54301',
   country: 'CZ',
} as const;

export type LoginOptions = {
   [key in keyof typeof testUser]?: (typeof testUser)[key];
};

export function register(): LoginOptions;
export function register(login: LoginOptions): LoginOptions;
export function register(login?: LoginOptions): LoginOptions {
   withPreviousUrl(() => {
      login = {
         ...testUser,
         ...(login ?? {}),
      };

      cy.visit('/');
      acceptAllCookies();
      cy.get('.cart-signin').click();
      cy.get('.c-userlogin-form [href*=registrace]').first().click();
      cy.wait(100); // hack - $ is not defined

      for (const [id, value] of Object.entries(login)) {
         if (id === 'country') {
            continue;
         }

         cy.get(`#${id}`).type(value, { force: true });
      }
      cy.get('#country').select(login.country);

      cy.get('.registration-submit > .btn').click();
   });

   return login;
}

export function login(): void;
export function login(email: string, password: string): void;
export function login(email?: string, password?: string): void {
   withPreviousUrl(() => {
      email ??= testUser.email;
      password ??= testUser.password;

      cy.visit('/');
      cy.get('.cart-signin').click();
      cy.get('#type_login').type(email);
      cy.get('#type_password').type(password);
      cy.get('#type_Submit').click();
   });
}

export function logout(): void {
   withPreviousUrl(() => {
      //Zakomentovat login() z duvodu registration.cy.ts, jelikoz nejprve probehne registrace a uzivatel je jiz prihlasen
      // tudiz problem s visit('/prihlaseni')
      // login();

      cy.visit('/ucet');
      cy.get('.item-logout > a').click();
   });
}

export function resetSoft() {
   cy.clearAllCookies();
   cy.clearAllLocalStorage();
   cy.clearAllSessionStorage();
}

export function resetHard(opts?: { baseUrl: string }) {
   let baseUrl: string;
   if (opts) {
      baseUrl = opts.baseUrl;
   } else {
      baseUrl = Cypress.config('baseUrl');
   }

   const url = new URL('/_cypress/resetHard', baseUrl);
   const response = syncFetch(url.href);

   // prime web server
   syncFetch(baseUrl);

   return response;
}

export function getNthProduct(idx: number = 0) {
   return cy.get('.c-section-products .c-productlist-squareitem').eq(idx);
}

export function fillCustomerInfo() {
   cy.get('.cart-nextstep-wrapper > .btn').click();
   cy.get('#iemail ').type(testUser.email);
   cy.get('#iname').type(testUser.name);
   cy.get('#isurname').type(testUser.surname);
   cy.get('#iphone').type(testUser.phone);
}

export function fillCustomerDeliveryInfo() {
   cy.get('.cart-nextstep-wrapper > .btn').click();
   cy.get('#iemail ').type(testUser.email);
   cy.get('#iname').type(testUser.name);
   cy.get('#isurname').type(testUser.surname);
   cy.get('#iphone').type(testUser.phone);
   cy.get('#istreet').type(testUser.street);
   cy.get('#icity').type(testUser.city);
   cy.get('#izip').type(testUser.zip);
}

export function priceEquals<Subject extends JQuery>(price: number): (fn: Subject) => void {
   return function (subject) {
      const actualPrice = +subject.text().replace(/\D/, '');
      cy.wrap(actualPrice).should('eq', price);
   };
}

export function getIframeDocument(selector: Selector): Chainable<JQuery> {
   return cy.get(selector).its('0.contentDocument').should('exist');
}

export function getIframeBody(selector: Selector): Chainable<JQuery> {
   return getIframeDocument(selector)
      .its('body')
      .should('not.be.undefined')
      .then((body: JQuery) => cy.wrap(body));
}

export function acceptAllCookies() {
   cy.get('.cookiebar-btns-simple .btn', { timeout: 10000 }).last().then(
      ($btn) => {
         if ($btn.is(':visible')) {
            cy.wrap($btn).click();
         }
      }
   );
}

export function visitProductDetail() {
   cy.wait(100);
   cy.visit('/celenka-mountains-black-white_z104/');
   gtm.dataLayerContainsEvent('page_view');
   gtm.dataLayerContainsEvent('view_item');
   gtm.dataLayerContainsEcommerceItem(gtm.getCelenkaEcommerceItem());
}

export function addProductToCart() {
   visitProductDetail();
   cy.get('.c-product-submitblock > .btn.c-product-addtocartbutton').first().click();
   gtm.dataLayerContainsEvent('add_to_cart');
   gtm.dataLayerEventContainsEcommerceItem('add_to_cart', {
      ...gtm.getCelenkaEcommerceItem(),
      quantity: 1,
   });
}

export function stepIntoCart() {
   cy.get('.cartbox-footer > .btn', { timeout: 30_000 }).first().click();
   cy.url().should('include', 'kosik');
   gtm.dataLayerContainsEvent('view_cart');
   cy.get('.cart-nextstep-wrapper > .btn', { timeout: 30_000 }).click();
}

export function clickMultisetSelectionButton(index: number) {
   cy.get('.jsmultisets-selected .item').eq(index - 1).find('a').click();
   cy.wait(500);
}

export function selectMultisetItem(index: number) {
   cy.get('.jsmultisets-selection-item-navigation .item').eq(index - 1).find('a').click();
}

export function selectMultisetVariation(text: string) {
   cy.get('.jsmultisets-product-variation').contains(text).click();
}

export function clickAddToSetButton() {
   cy.get('.jsmultisets-sidebar-submit button').click();
}
