import { db } from '$lib/database'
import type { Err } from '$lib/types'

export type Food = {
	rowid?: number,
	date?: Date,
	food: string,
	description?: string,
	amount: number,
	per100?: number,
	energy?: number,
}

export type AggregatedFood = {
	period: string,
	amount: number,
	avgPer100: number,
	energy: number,
}

const columns = ['rowid', 'date', 'food', 'description', 'amount', 'per100', 'energy']
const aggColumns = ['period', 'amount', 'avgPer100', 'energy']

const FoodService = {
	async GetAll() {
		return await db.select<Food[]>(`
select ${columns.join(', ')}
from food
order by date desc
		`)
	},
	async GetAllForDate(date: Date) {
		return await db.select<Food[]>(`
select ${columns.join(', ')}
from foodView
where strftime('%Y-%m-%d', date) = strftime('%Y-%m-%d', '2024-06-12')
or strftime('%Y-%m-%d', date) = strftime('%Y-%m-%d', date('2024-06-12', '-1 day'))
order by date DESC;
`, [date])
	},
	async Create(food: Food): Promise<[Food, Err]> {
		if (!food.food) return [food, 'food.food is required']
		if (!food.amount) throw [food, 'food.amount is required']

		let res
		if (!!food.per100)
			res = await db.execute(`insert into food (food, description, amount, per100) values ($1, $2, $3, $4)`, [food.food, food.description, food.amount, food.per100])
		else
			res = await db.execute(`insert into food (food, description, amount) values ($1, $2, $3)`, [food.food, food.description, food.amount])
		const rows = await db.select<Food[]>(`select ${columns.join(', ')} from foodView where rowid = $1`, [res.lastInsertId])

		if (!rows) return [food, 'no data found']
		if (rows.length == 0) return [food, 'no data found']
		// Its not undefined mannnnnnnnnnnnnnnnnnnnnnnnnn............
		// @ts-ignore
		return [rows[0], null]
	},
	async GetLatestPer100(food: string): Promise<[number, Err]> {
		if (!food) return [-1, 'food is required']
		const rows: { per100: number }[] = await db.select<{ per100: number }[]>(`
select per100
from foodView
where food = $1
	and per100 is not null
order by date desc
limit 1
		`, [food])
		if (!rows) return [-1, 'no data found']
		if (rows.length == 0) return [-1, 'no data found']
		// @ts-ignore
		return [rows[0].per100, null]
	},
	async GetDaily(): Promise<[AggregatedFood[], Err]> {
		const rows = await db.select<AggregatedFood[]>(`select ${aggColumns.join(', ')} from daily limit 100`)
		return [rows, null]
	},
	async GetWeekly(): Promise<[AggregatedFood[], Err]> {
		const rows = await db.select<AggregatedFood[]>(`select ${aggColumns.join(', ')} from weekly limit 100`)
		return [rows, null]
	},
	async GetMonthly(): Promise<[AggregatedFood[], Err]> {
		const rows = await db.select<AggregatedFood[]>(`select ${aggColumns.join(', ')} from monthly limit 100`)
		return [rows, null]
	},
	async GetYearly(): Promise<[AggregatedFood[], Err]> {
		const rows = await db.select<AggregatedFood[]>(`select ${aggColumns.join(', ')} from yearly limit 100`)
		return [rows, null]
	},
	async Update(food: Food): Promise<[Food, Err]> {
		await db.execute(`
update food set
food = $1,
description = $2,
amount = $3,
per100 = $4
where rowid = $5
		`, [food.food, food.description, food.amount, food.per100, food.rowid])
		const res = await db.select<Food[]>(`select ${columns.join(', ')} from foodView where rowid = $1`, [food.rowid])
		if (!res) return [food, 'no data found']
		if (res.length == 0) return [food, 'no data found']
		if (!res[0]) return [food, 'no data found']
		return [res[0], null]
	}
}

export { FoodService }
