from __future__ import annotations

import collections
import dataclasses
import json
import sys
import typing

import cache
import company
import integration
import planet_bases

def main() -> None:
	cx, ticker = sys.argv[1:]

	(expertise,) = frozenset(iter_expertise(ticker))

	planets: dict[str, str] = {}
	for planet, cogc in company.iter_planet_cogc():
		if cogc == expertise:
			planets[planet['PlanetId']] = planet['PlanetName']
	print(len(planets), 'with', expertise, 'CoGC')

	with open('www/closest.json') as f:
		close_planet_ids = {planet_id for planet_id, closest_cx in json.load(f).items() if closest_cx == cx}

	coid_code_name: dict[str, tuple[str, str]] = {}
	coid_bases = collections.defaultdict(list)
	for planet_id, planet_name in planets.items():
		if planet_id in close_planet_ids:
			print(f'\t\033[32m{planet_name}\033[0m')
		else:
			print(f'\t\033[31m{planet_name}\033[0m')
		bases = planet_bases.get_bases(planet_name)
		for base in bases:
			if (code := base['OwnerCode']) is None:
				continue
			coid_code_name[base['OwnerId']] = code, base['OwnerName']
			coid_bases[base['OwnerId']].append(planet_id)

	coid_users: dict[str, str] = {company_id: d['Username']
		for company_id, d in cache.get('https://pmmg-products.github.io/reports/data/knownCompanies.json', expiry=cache.ONE_DAY).items()}

	competitors: list[Competitor] = []
	for company_id, co_production in integration.pmmg_monthly_report().items():
		if (mat_production := co_production.get(ticker)) is None:
			continue
		if planet_ids := coid_bases.get(company_id):
			code, co_name = coid_code_name[company_id]
			username = coid_users.get(company_id, '[unknown]')
			competitors.append(Competitor(code, co_name, username, mat_production['amount'], planet_ids))
	competitors.sort(reverse=True)

	total = 0.0
	for c in competitors:
		close_planet_num = 0
		player_planets = []
		for planet_id in c.planet_ids:
			if planet_id in close_planet_ids:
				player_planets.append(f'\033[32m{planets[planet_id]}\033[0m')
				close_planet_num += 1
			else:
				player_planets.append(f'\033[31m{planets[planet_id]}\033[0m')

		if close_planet_num > 0:
			local_production = c.production * close_planet_num / len(c.planet_ids)
			total += local_production
			print(f'{c.code:4} {c.company_name:30} {c.username:20} {local_production:9,.1f} ', ' '.join(player_planets))
	print(f'total: {total:,.1f}')

def iter_expertise(ticker: str) -> typing.Iterator[str]:
	buildings: typing.Sequence[company.Building] = cache.get('https://rest.fnar.net/building/allbuildings', expiry=cache.ONE_DAY)
	for building in buildings:
		for recipe in building['Recipes']:
			for output in recipe['Outputs']:
				if output['CommodityTicker'] == ticker:
					print(ticker, 'requires', building['Expertise'])
					yield building['Expertise']

@dataclasses.dataclass(eq=False, frozen=True, slots=True)
class Competitor:
	code: str
	company_name: str
	username: str
	production: float
	planet_ids: typing.Sequence[str]

	def __lt__(self, other: Competitor) -> bool:
		return self.production < other.production

if __name__ == '__main__':
	main()
