// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use super::EffectController;

use crate::server::multiplayer::config::{EventConfig, EffectZone as ConfigEffectZone, EffectZoneDefaultColourConfig};
use crate::utils::maths::{RectCorners, CollidingRect};
use crate::world::{World, special_area::SpecialArea, effects::{Effect, EffectInfo}};

pub struct EffectZones(Box<[EffectZone]>);

struct EffectZone {
	rect: RectCorners,
	effect: Effect,
	info: EffectInfo,
}

impl EffectZones {
	pub fn new(zones: Box<[ConfigEffectZone]>, event_config: &EventConfig, default_colours: EffectZoneDefaultColourConfig, special_areas: &mut Vec<SpecialArea>) -> EffectZones {
		EffectZones(zones.into_vec().into_iter().map(|zone| {
			let colour = zone.colour.unwrap_or(match zone.effect {
				Effect::Speed => default_colours.speed,
				Effect::Reload => default_colours.reload,
				Effect::Regeneration => default_colours.regen,
				Effect::Damage => default_colours.damage,
				Effect::Forcefield => default_colours.forcefield,
			});

			special_areas.extend_from_slice(&SpecialArea::rect(zone.rect, colour));

			EffectZone {
				rect: zone.rect,
				effect: zone.effect,
				info: EffectInfo { time: zone.time, power: zone.power.unwrap_or_else(|| event_config.effects.get_effect_power(zone.effect)) },
			}
		}).collect::<Vec<_>>().into_boxed_slice())
	}

	pub fn update(&self, world: &World, effect_controller: &mut EffectController) {
		for (&id, player) in world.get_players() {
			for zone in &self.0 {
				if player.colliding_rect(&zone.rect) {
					effect_controller.in_zone(id, zone.effect, zone.info);
				}
			}
		}
	}
}
