<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Uploader — thin convenience wrapper around CI's Upload library, used by
 * the admin controllers so upload configuration isn't duplicated.
 */
#[\AllowDynamicProperties]
class Uploader {

	protected $CI;

	public function __construct()
	{
		$this->CI =& get_instance();
	}

	/**
	 * Handle a single file upload.
	 *
	 * @param  string $field   The $_FILES field name.
	 * @param  string $folder  Sub-folder under assets/uploads/.
	 * @param  string $types   Pipe-separated allowed extensions.
	 * @param  int    $max_size Max size in KB. NULL = use the default image limit.
	 * @return string|null     Relative path (folder/file) on success, or NULL.
	 */
	public function file($field, $folder, $types = 'jpg|jpeg|png|webp', $max_size = NULL)
	{
		if (empty($_FILES[$field]['name']))
		{
			return NULL;
		}

		$path = FCPATH.'assets/uploads/'.$folder.'/';
		if ( ! is_dir($path))
		{
			@mkdir($path, 0755, TRUE);
		}

		if ($max_size === NULL)
		{
			$max_size = $this->CI->config->item('upload_max_size') ?: 20480;
		}

		$config = array(
			'upload_path'   => $path,
			'allowed_types' => $types,
			'max_size'      => $max_size,
			'file_name'     => $folder.'-'.time().'-'.bin2hex(random_bytes(3)),
			'encrypt_name'  => FALSE,
		);

		$this->CI->load->library('upload', $config);
		$this->CI->upload->initialize($config);

		if ($this->CI->upload->do_upload($field))
		{
			return $folder.'/'.$this->CI->upload->data('file_name');
		}

		// Surface the error to the user via flashdata.
		$this->CI->session->set_flashdata('error',
			$this->CI->upload->display_errors('', ''));
		return NULL;
	}

	/**
	 * Handle multiple file uploads from a single multi-file field.
	 * Returns an array of relative paths.
	 */
	public function files($field, $folder, $types = 'jpg|jpeg|png|webp')
	{
		if (empty($_FILES[$field]['name']) || ! is_array($_FILES[$field]['name']))
		{
			return array();
		}

		$path = FCPATH.'assets/uploads/'.$folder.'/';
		if ( ! is_dir($path))
		{
			@mkdir($path, 0755, TRUE);
		}

		$saved = array();
		$count = count($_FILES[$field]['name']);

		for ($i = 0; $i < $count; $i++)
		{
			if (empty($_FILES[$field]['name'][$i])) continue;

			// Re-map to a single-file structure CI's Upload expects.
			$_FILES['_one'] = array(
				'name'     => $_FILES[$field]['name'][$i],
				'type'     => $_FILES[$field]['type'][$i],
				'tmp_name' => $_FILES[$field]['tmp_name'][$i],
				'error'    => $_FILES[$field]['error'][$i],
				'size'     => $_FILES[$field]['size'][$i],
			);

			$config = array(
				'upload_path'   => $path,
				'allowed_types' => $types,
				'max_size'      => $this->CI->config->item('upload_max_size') ?: 20480,
				'file_name'     => $folder.'-'.time().'-'.bin2hex(random_bytes(4)),
				'encrypt_name'  => FALSE,
			);
			$this->CI->load->library('upload', $config);
			$this->CI->upload->initialize($config);

			if ($this->CI->upload->do_upload('_one'))
			{
				$saved[] = $folder.'/'.$this->CI->upload->data('file_name');
			}
		}

		unset($_FILES['_one']);
		return $saved;
	}

	/** Delete an uploaded file by its relative path. */
	public function remove($relative_path)
	{
		if (empty($relative_path)) return FALSE;
		$full = FCPATH.'assets/uploads/'.$relative_path;
		if (is_file($full))
		{
			return @unlink($full);
		}
		return FALSE;
	}
}
