from chargefile import ChargeFile, SearchDirection

CYCLES_PER_STEP = 4
STEP_COUNT = 12


def charge_cylces_in_step(globalstep: int):
	cyclepoint = globalstep % STEP_COUNT
	if cyclepoint == 0:
		if (globalstep / STEP_COUNT) % 10 == 0:
			return 1
		else:
			return 0
	if cyclepoint == 9:
		return 1
	if cyclepoint == 11:
		return CYCLES_PER_STEP
	return 0


def charge_cycles_at_step(globalstep: int,):
	count = 0
	for i in range(globalstep):
		count += charge_cylces_in_step(i)
	return count


def thermal_cylces_in_step(globalstep: int, substep: int = -1):
	cyclepoint = globalstep % STEP_COUNT
	if cyclepoint == 0:
		if (globalstep / STEP_COUNT) % 10 == 0:
			return 0
		else:
			return CYCLES_PER_STEP
	if cyclepoint == 2:
		return CYCLES_PER_STEP
	if cyclepoint == 4:
		return CYCLES_PER_STEP
	if cyclepoint == 6:
		return CYCLES_PER_STEP
	if cyclepoint == 8:
		return CYCLES_PER_STEP
	if cyclepoint == 10:
		return CYCLES_PER_STEP
	if cyclepoint == 11:
		return 1
	return 0


def thermal_cycles_at_step(globalstep: int, substep: int):
	count = 0
	for i in range(globalstep - 1):
		count += thermal_cylces_in_step(globalstep)
	count += thermal_cylces_in_step(globalstep, substep)
	return count


non_charge_cycle_cell = list(range(4, 7))
non_thermal_cycle_cell = list(range(11, 21))
cell_thermal_range = {
	0: [35, 55],
	1: [35, 55],
	2: [35, 55],
	3: [35, 55],
	4: [35, 55],
	5: [35, 55],
	6: [35, 55],
	7: [35, 45],
	8: [35, 45],
	9: [35, 45],
	10: [35, 45],
	11: [35, 35],
	12: [35, 35],
	13: [35, 35],
	14: [45, 45],
	15: [45, 45],
	16: [45, 45],
	17: [35, 55],
	18: [35, 55],
	19: [35, 55],
	20: [35, 55],
}

cell_group_table = {
	0: 0,
	1: 0,
	2: 0,
	3: 0,
	4: 1,
	5: 1,
	6: 1,
	7: 2,
	8: 2,
	9: 2,
	10: 2,
	11: 3,
	12: 3,
	13: 3,
	14: 4,
	15: 4,
	16: 4,
	17: 5,
	18: 5,
	19: 5,
	20: 5,
}


class CellMeta:
	def __init__(self, cellid: int, globalstep: int, substep: int, charge_files: list[ChargeFile], total_cells: int):
		closest_avg = None
		closest_charge = None
		if cellid not in non_charge_cycle_cell:
			closest_avg = ChargeFile.FindClosest(charge_files, globalstep, -1)
			closest_charge = ChargeFile.FindClosest(charge_files, globalstep, cellid)
		if closest_charge is not None:
			assert closest_charge.cell == cellid

		total_charge_cells = 0
		for i in range(total_cells):
			if i not in non_charge_cycle_cell:
				total_charge_cells += 1

		self.cell_group = cell_group_table[cellid]
		self.charge_cycles = charge_cycles_at_step(globalstep) if cellid not in non_charge_cycle_cell else 0
		self.thermal_cycles = thermal_cycles_at_step(globalstep, substep) if cellid not in non_thermal_cycle_cell else 0
		self.last_avg_cap = abs(closest_avg.capacity) / total_charge_cells if closest_avg is not None else -1
		self.last_avg_cap_step = closest_avg.step if closest_avg is not None else -1
		self.last_cap = abs(closest_charge.capacity) if closest_charge is not None else -1
		self.last_cap_step = closest_charge.step if closest_charge is not None else -1
		self.thermal_range = cell_thermal_range[cellid]
		if cellid not in non_charge_cycle_cell:
			self.soc = ChargeFile.GetSoc(charge_files, globalstep, cellid, total_charge_cells)
			self.cap_esitmate = ChargeFile.GetCapacityEsitmate(charge_files, globalstep, cellid, total_charge_cells)
		else:
			self.soc = -1
			self.cap_esitmate = -1
		self.soc_estimate = -1
