from __future__ import annotations
import collections
import dataclasses
import typing

import httpx
import tap

from config import config

class Args(tap.Tap):
	planet: str | None = None
	usernames: tuple[str, ...] = ()

def main():
	args = Args().parse_args()
	params = {}
	if args.usernames:
		params['usernames'] = ','.join(args.usernames)
	elif args.planet:
		params['location'] = args.planet
	users: typing.Sequence[ProductionUser] = httpx.get('https://api.punoted.net/v1/production/', params=params,
			headers={'X-Data-Token': config.punoted_api_key}).raise_for_status().json()
	ms_in_day = 24 * 60 * 60 * 1000
	for user in users:
		print(user['Username'])
		for line in user['Production']:
			print('    ' + line['PlanetName'], f'{line["Capacity"]}×{line["Type"]}', line['Efficiency'], line['Condition'])
			production: dict[str, Production] = {}
			for order in line['Orders']:
				if order['CompletedPercentage'] is not None:
					continue
				for output in order['Outputs']:
					production[output['ProductionLineOutputId']] = Production(
						ticker=output['MaterialTicker'],
						amount=output['MaterialAmount'],
						duration_ms=order['DurationMs']
					)
			line_queued_time = sum(p.duration_ms for p in production.values())
			line_outputs: dict[str, float] = collections.defaultdict(float)
			for p in production.values():
				amount = p.amount * ms_in_day / line_queued_time * line['Capacity']
				line_outputs[p.ticker] += amount
			for ticker, amount in line_outputs.items():
				print(f'        {amount}×{ticker}')

@dataclasses.dataclass
class Production:
	ticker: str
	amount: float
	duration_ms: int

class ProductionUser(typing.TypedDict):
	Username: str
	Production: typing.Sequence[ProductionLine]

class ProductionLine(typing.TypedDict):
	PlanetName: str
	Type: str
	Capacity: int
	Efficiency: float
	Condition: float
	Orders: typing.Sequence[ProductionOrder]

class ProductionOrder(typing.TypedDict):
	CompletedPercentage: float | None
	DurationMs: int
	Outputs: typing.Sequence[ProductionOutput]

class ProductionOutput(typing.TypedDict):
	ProductionLineOutputId: str
	MaterialTicker: str
	MaterialAmount: float

if __name__ == '__main__':
	main()
