import {
	IPage,
	ISearchItem,
	ISearchParams,
	ISearchProvider,
	IYahooFleamarketProductItem,
	Order,
	Sort,
	StationId
} from "../type";
import {beginToPage, queryNextData, wrappedFetch} from "../lib";

export class Provider10YahooFleamarket implements ISearchProvider {
	readonly stationId = StationId.YahooFleamarket;

	async search(params: ISearchParams): Promise<IPage> {
		const {keyword, begin = 1, maxNum = 50, category, minPrice, maxPrice, shipping, sort, order} = params;
		const pageNum = beginToPage(begin, maxNum);
		const warn: string[] = [];
		const url = new URL(`https://paypayfleamarket.yahoo.co.jp/search/${keyword}`);
		url.searchParams.set("page", String(pageNum));
		url.searchParams.set("n", String(maxNum));
		if (category) {
			url.searchParams.set("categoryIds", category);
		}
		if (minPrice) {
			url.searchParams.set("minPrice", String(minPrice));
		}
		if (maxPrice) {
			url.searchParams.set("maxPrice", String(maxPrice));
		}
		if (shipping === 'free') {
			warn.push('unsupported free shipping');
		}
		if (sort) {
			if (sort === Sort.Latest) {
				url.searchParams.set("sort", 'openTime');
				if (order === Order.Asc) {
					url.searchParams.set("order", 'asc');
				} else {
					url.searchParams.set("order", 'desc');
				}
			} else if (sort ===Sort.Price) {
				url.searchParams.set("sort", 'price');
				if (order === Order.Desc) {
					url.searchParams.set("order", 'desc');
				} else {
					url.searchParams.set("order", 'asc');
				}
			} else if(sort!==Sort.Default) {
				warn.push(`unsupported sort: ${sort}`);
			}
		}

		const resp = await wrappedFetch(url);

		if (!resp.ok) {
			if (resp.status === 404) {
				return {...params, dataList: [], error: '404 Not Found'};
			}
			return {...params, dataList: [], error: `HTTP error! status: ${resp.status}`};
		}

		// noinspection TypeScriptUnresolvedReference
		const html = await resp.text();
		const result = parseProducts(html);

		return {
			srcUrl: url.toString(),
			warning: warn.join(', '),
			begin,
			maxNum,
			pageNum,
			...params,
			...result,
		};
	}
}

function parseProducts(docHtml: string): Omit<IPage, keyof ISearchParams> {
	const nextProps = queryNextData(docHtml);
	const result = nextProps?.initialState?.searchState?.search?.result;
	const dataList = result?.items.map(parseItem) || [];

	return {
		total: Math.max(result?.totalResultsAvailable || 0, dataList.length),
		dataList
	};
}


function parseItem(item: IYahooFleamarketProductItem): ISearchItem {
	return {
		itemId: item.id,
		url: `https://paypayfleamarket.yahoo.co.jp/item/${item.id}`,
		image: {
			imageUrl: item.thumbnailImageUrl,
		},
		name: item.title,
		time: item.endTime,
		price: item.price,
	};
}