<?php

class Pota extends CI_Model {

	public function split_refs($value) {
		if ($value === null || $value === '') {
			return [];
		}

		$parts = preg_split('/\s*,\s*/', strtoupper(trim((string)$value)));
		$parts = array_filter($parts, static function($part) {
			return $part !== '';
		});

		return array_values(array_unique($parts));
	}

	public function collect_refs_from_rows($rows) {
		$refs = [];
		foreach ($rows as $row) {
			foreach ($this->split_refs($row->COL_POTA_REF ?? '') as $ref) {
				$refs[$ref] = true;
			}
		}

		return array_keys($refs);
	}

	// Existing method used by current simple table
	function get_all() {
		$CI =& get_instance();
		$CI->load->model('logbooks_model');
		$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));

		if (!$logbooks_locations_array) {
			return null;
		}

		$this->load->model('bands');

		$bandslots = $this->bands->get_worked_bands('pota');

		if(!$bandslots) return null;

		$this->db->where_in("station_id", $logbooks_locations_array);
		$this->db->where_in("col_band", $bandslots);
		$this->db->order_by("COL_POTA_REF", "ASC");
		$this->db->where('COL_POTA_REF !=', '');

		return $this->db->get($this->config->item('table_name'));
	}

	// New: generic filtered fetch for HTMX table
	function fetch_qsos($filters) {
		$CI =& get_instance();
		$CI->load->model('logbooks_model');
		$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));

		if (!$logbooks_locations_array) {
			return [];
		}

		$this->db->from($this->config->item('table_name'));
		$this->db->where_in('station_id', $logbooks_locations_array);
		$this->db->where('COL_POTA_REF !=', '');

		$this->apply_filters($filters);

		$this->db->order_by('COL_TIME_ON', 'DESC');
		$query = $this->db->get();
		return $query->result();
	}

	// New: first and last QSO timestamps/refs within filters
	function get_first_last($filters) {
		$CI =& get_instance();
		$CI->load->model('logbooks_model');
		$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
		if (!$logbooks_locations_array) {
			return ['first'=>null,'last'=>null];
		}

		// first
		$this->db->from($this->config->item('table_name'));
		$this->db->where_in('station_id', $logbooks_locations_array);
		$this->db->where('COL_POTA_REF !=', '');
		$this->apply_filters($filters);
		$this->db->order_by('COL_TIME_ON', 'ASC');
		$this->db->limit(1);
		$first = $this->db->get()->row();

		// last
		$this->db->from($this->config->item('table_name'));
		$this->db->where_in('station_id', $logbooks_locations_array);
		$this->db->where('COL_POTA_REF !=', '');
		$this->apply_filters($filters);
		$this->db->order_by('COL_TIME_ON', 'DESC');
		$this->db->limit(1);
		$last = $this->db->get()->row();

		return ['first'=>$first, 'last'=>$last];
	}

	// New: unique parks and optionally by band/mode
	function get_uniques($filters, $by = null) {
		$CI =& get_instance();
		$CI->load->model('logbooks_model');
		$logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
		if (!$logbooks_locations_array) {
			return [];
		}

		$this->db->select('COL_POTA_REF, COL_BAND, COL_MODE, COL_SUBMODE');
		$this->db->from($this->config->item('table_name'));
		$this->db->where_in('station_id', $logbooks_locations_array);
		$this->db->where('COL_POTA_REF !=', '');
		$this->apply_filters($filters);

		$rows = $this->db->get()->result();

		if (!$by) {
			return count($this->collect_refs_from_rows($rows));
		}

		$out = [];
		foreach ($rows as $row) {
			$key = $by === 'band'
				? $row->COL_BAND
				: (($row->COL_SUBMODE !== null && $row->COL_SUBMODE !== '') ? $row->COL_SUBMODE : $row->COL_MODE);

			if (!isset($out[$key])) {
				$out[$key] = [];
			}

			foreach ($this->split_refs($row->COL_POTA_REF) as $ref) {
				$out[$key][$ref] = true;
			}
		}

		foreach ($out as $key => $refs) {
			$out[$key] = count($refs);
		}

		return $out;
	}

	// New: confirmation counts
	function get_confirmations($filters) {
		$filtersConfirmed = $filters;
		$filtersConfirmed['confirmed'] = true;
		return $this->get_uniques($filtersConfirmed);
	}

	// New: read assets/json/pota_parks.csv and map refs to metadata
	function get_parks_meta($refs) {
		$refs = array_values(array_unique(array_filter($refs)));
		if (empty($refs)) return [];

		// Read only the needed refs from CSV to keep memory low
		$out = $this->load_parks_subset($refs);

		// If still missing coords, we skip map markers quietly
		return $out;
	}

	private function load_parks_subset($wantedRefs) {
		$path = FCPATH . 'assets/json/pota_parks.csv';
		if (!file_exists($path)) return [];

		$wantedSet = array_fill_keys($wantedRefs, true);
		$found = [];

		$fh = fopen($path, 'r');
		if ($fh === false) return [];

		$header = fgetcsv($fh);
		if ($header === false) { fclose($fh); return []; }
		$idx = $this->map_header_indices($header);

		while (($cols = fgetcsv($fh)) !== false) {
			if (!isset($cols[$idx['ref']])) continue;
			$ref = trim($cols[$idx['ref']]);
			if ($ref === '' || !isset($wantedSet[$ref])) continue;

			$found[$ref] = [
				'name' => $idx['name'] !== null && isset($cols[$idx['name']]) ? $cols[$idx['name']] : null,
				'entity' => $idx['entity'] !== null && isset($cols[$idx['entity']]) ? $cols[$idx['entity']] : null,
				'country' => $idx['country'] !== null && isset($cols[$idx['country']]) ? $cols[$idx['country']] : null,
				'lat' => $idx['lat'] !== null && isset($cols[$idx['lat']]) ? floatval($cols[$idx['lat']]) : null,
				'lon' => $idx['lon'] !== null && isset($cols[$idx['lon']]) ? floatval($cols[$idx['lon']]) : null,
			];

			// Early exit if we got all requested refs
			if (count($found) === count($wantedSet)) {
				break;
			}
		}
		fclose($fh);
		return $found;
	}

	private function map_header_indices($header) {
		$find = function($candidates) use ($header) {
			foreach ($header as $i => $h) {
				$hn = strtolower(trim($h));
				foreach ($candidates as $cand) {
					if ($hn === $cand) return $i;
					if (strpos($hn, $cand) !== false) return $i;
				}
			}
			return null;
		};
		// Try to detect columns by common names
		$refIdx = $find(['ref','reference','park id','park','entity id']);
		if ($refIdx === null) $refIdx = 0; // fallback to first column
		return [
			'ref' => $refIdx,
			'name' => $find(['name','park name','designation']),
			'entity' => $find(['entity','state','province','region']),
			'country' => $find(['country','country code']),
			'lat' => $find(['lat','latitude']),
			'lon' => $find(['lon','longitude','lng']),
		];
	}

	private function apply_filters($filters) {
		// Date range
		if (!empty($filters['from'])) {
			$this->db->where('COL_TIME_ON >=', $filters['from'] . ' 00:00:00');
		}
		if (!empty($filters['to'])) {
			$this->db->where('COL_TIME_ON <=', $filters['to'] . ' 23:59:59');
		}

		// Band / SAT
		if (!empty($filters['band']) && $filters['band'] !== 'All') {
			if ($filters['band'] === 'SAT') {
				$this->db->where('COL_PROP_MODE', 'SAT');
			} else {
				$this->db->where('(COL_PROP_MODE IS NULL OR COL_PROP_MODE <> "SAT")', null, false);
				$this->db->where('COL_BAND', $filters['band']);
			}
		}

		// Mode
		if (!empty($filters['mode']) && $filters['mode'] !== 'All') {
			$this->db->group_start();
			$this->db->where('COL_MODE', $filters['mode']);
			$this->db->or_where('COL_SUBMODE', $filters['mode']);
			$this->db->group_end();
		}

		// Confirmed only
		if (!empty($filters['confirmed'])) {
			$this->db->group_start();
			$this->db->where('col_qsl_rcvd', 'Y');
			$this->db->or_where('col_lotw_qsl_rcvd', 'Y');
			$this->db->group_end();
		}
	}
}

?>
