import axios from 'axios';
import { load } from 'cheerio';
import { getPizzaListMock, getSalatListMock } from './mock';
import { Salat } from '../../types/gen/types.gen';

// TODO přesunout do types
type PizzaSize = {
    varId: number,
    size: string,
    pizzaPrice: number,
    boxPrice: number,
    price: number
}

// TODO přesunout do types
type Pizza = {
    name: string,
    ingredients: string[],
    sizes: PizzaSize[],
}

// TODO mělo by být konfigurovatelné proměnnou z prostředí s tímhle jako default
const baseUrl = 'https://www.pizzachefie.cz';
const pizzyUrl = `${baseUrl}/pizzy.html`;
const salayUrl = `${baseUrl}/salaty.html`;

const buildPizzaUrl = (pizzaUrl: string) => {
    return `${baseUrl}/${pizzaUrl}`;
}

// Ceny krabic dle velikosti
const boxPrices: { [key: string]: number } = {
    "30cm": 13,
    "35cm": 15,
    "40cm": 18,
    "50cm": 25
}

// Cena obalu pro salát
const SALAT_BOX_PRICE = 13;

/**
 * Stáhne a scrapne aktuální pizzy ze stránek Pizza Chefie.
 *
 * @param mock zda vrátit pouze mock data
 */
export async function downloadPizzy(mock: boolean): Promise<Pizza[]> {
    if (mock) {
        // Záměrné zpoždění pro testování
        return new Promise((resolve) => setTimeout(() => resolve(getPizzaListMock()), 3000));
    }
    // Získáme seznam pizz
    const html = await axios.get(pizzyUrl).then(res => res.data);
    const $ = load(html);
    const links = $('.vypisproduktu > div > h4 > a');
    const urls = [];
    for (const element of links) {
        if (element.name === 'a' && element.attribs?.href) {
            const pizzaUrl = element.attribs?.href;
            urls.push(buildPizzaUrl(pizzaUrl));
        }
    }
    // Scrapneme jednotlivé pizzy
    const result: Pizza[] = [];
    for (const element of urls) {
        const pizzaUrl = element;
        const pizzaHtml = await axios.get(pizzaUrl).then(res => res.data);
        // Název
        const name = $('.produkt > h2', pizzaHtml).first().text()
        // Přísady
        const ingredients: string[] = []
        const ingredientsHtml = $('.prisady > li', pizzaHtml);
        ingredientsHtml.each((i, elm) => {
            ingredients.push($(elm).text());
        })
        // Velikosti
        const sizes: PizzaSize[] = [];
        const a = $('.varianty > li > a', pizzaHtml);
        a.each((i, elm) => {
            const varId = Number.parseInt(elm.attribs.href.split('?varianta=')[1].trim());
            const size = $($(elm).contents().get(0)).text().trim();
            const price = Number.parseInt($($(elm).contents().get(1)).text().trim().split(" Kč")[0]);
            sizes.push({ varId, size, pizzaPrice: price, boxPrice: boxPrices[size], price: price + boxPrices[size] });
        })
        result.push({
            name: name,
            ingredients: ingredients,
            sizes: sizes,
        });
    }
    return result;
}

/**
 * Stáhne a scrapne aktuální saláty ze stránek Pizza Chefie.
 * Příplatek za obal je pro každý salát pevně 13 Kč.
 *
 * @param mock zda vrátit pouze mock data
 */
export async function downloadSalaty(mock: boolean): Promise<Salat[]> {
    if (mock) {
        return new Promise((resolve) => setTimeout(() => resolve(getSalatListMock()), 1000));
    }
    const html = await axios.get(salayUrl).then(res => res.data);
    const $ = load(html);
    const links = $('.vypisproduktu > div > h4 > a');
    const urls = [];
    for (const element of links) {
        if (element.name === 'a' && element.attribs?.href) {
            urls.push(buildPizzaUrl(element.attribs.href));
        }
    }
    const result: Salat[] = [];
    for (const url of urls) {
        const salatHtml = await axios.get(url).then(res => res.data);
        const name = $('.produkt > h2', salatHtml).first().text().trim();
        const ingredients: string[] = [];
        $('.prisady > li', salatHtml).each((i, elm) => {
            ingredients.push($(elm).text());
        });
        const priceText = $('.cena > span', salatHtml).first().text().trim();
        const price = Number.parseInt(priceText.split(' Kč')[0]);
        result.push({ name, ingredients, price: price + SALAT_BOX_PRICE });
    }
    return result;
}