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

class Episodes extends CI_Controller
{
	public function __construct()
	{
		parent::__construct();
		$this->load->helper(['url', 'form']);
		$this->load->library(['session', 'template', 'firebase']);
		$this->load->model('common');
	}

	private function uuidV4Upper()
	{
		$data = random_bytes(16);
		$data[6] = chr((ord($data[6]) & 0x0f) | 0x40);
		$data[8] = chr((ord($data[8]) & 0x3f) | 0x80);
		$hex = strtoupper(bin2hex($data));
		return sprintf(
			'%s-%s-%s-%s-%s',
			substr($hex, 0, 8),
			substr($hex, 8, 4),
			substr($hex, 12, 4),
			substr($hex, 16, 4),
			substr($hex, 20, 12)
		);
	}

	private function normalizeEpisodeInput($input)
	{
		$duration = isset($input['duration']) ? (float)$input['duration'] : 0.0;

		return [
			'title' => isset($input['title']) ? trim((string)$input['title']) : '',
			'aboutDescription' => isset($input['aboutDescription']) ? trim((string)$input['aboutDescription']) : '',
			'goals' => isset($input['goals']) ? trim((string)$input['goals']) : '',
			'length' => isset($input['length']) ? trim((string)$input['length']) : '',
			'sets' => isset($input['sets']) ? trim((string)$input['sets']) : '',
			'time' => isset($input['time']) ? trim((string)$input['time']) : '',
			'duration' => $duration,
			'videoUri' => isset($input['videoUri']) ? trim((string)$input['videoUri']) : '',
		];
	}

	private function uploadEpisodeVideoIfPresent($courseId, $episodeId, $existingUrl = '')
	{
		if (empty($_FILES['video_file']) || empty($_FILES['video_file']['tmp_name'])) {
			return $existingUrl;
		}

		$tmp = $_FILES['video_file']['tmp_name'];
		$objectName = 'course_videos/' . $courseId . '/episode_' . $episodeId . '.mp4';

		$firebase = $this->firebase->init();
		$storage = $firebase->createStorage();
		$bucket = $storage->getBucket();

		$uploaded = $bucket->upload(
			file_get_contents($tmp),
			[
				'name' => $objectName,
				// keep consistent with existing codebase usage
				'predefinedAcl' => 'publicRead',
			]
		);

		$info = $uploaded->info();
		if (!empty($info['mediaLink'])) {
			return (string)$info['mediaLink'];
		}

		// fallback
		return 'https://storage.googleapis.com/' . $bucket->name() . '/' . $objectName;
	}

	public function index($courseId)
	{
		$data['courseId'] = $courseId;
		$data['course'] = $this->common->readdatadocument('courses', $courseId);
		$data['episodes'] = $this->common->readdatacollection('courses', 'Episode', $courseId);
		$this->template->template_render('episodes_crud/index', $data);
	}

	public function create($courseId)
	{
		$data['courseId'] = $courseId;
		$data['episodeId'] = null;
		$data['episode'] = null;
		$data['mode'] = 'create';
		$this->template->template_render('episodes_crud/form', $data);
	}

	public function store($courseId)
	{
		$post = $this->input->post();
		$episodeId = $this->uuidV4Upper();
		$data = $this->normalizeEpisodeInput($post);

		$data['episodeID'] = $episodeId;
		$data['videoUri'] = $this->uploadEpisodeVideoIfPresent($courseId, $episodeId, $data['videoUri']);

		$response = $this->common->adddatamodelnexted('courses', $courseId, 'Episode', $episodeId, $data);
		if ($response) {
			$this->session->set_flashdata('successmessage', 'Episode created successfully');
		} else {
			$this->session->set_flashdata('warningmessage', 'Failed to create episode');
		}
		redirect(base_url('episodes/index/' . $courseId));
	}

	public function edit($courseId, $episodeId)
	{
		$data['courseId'] = $courseId;
		$data['episodeId'] = $episodeId;
		$data['episode'] = $this->common->readdatacollection('courses', 'Episode', $courseId)[$episodeId] ?? null;
		if (!$data['episode']) {
			$this->session->set_flashdata('warningmessage', 'Episode not found');
			redirect(base_url('episodes/index/' . $courseId));
			return;
		}
		$data['mode'] = 'edit';
		$this->template->template_render('episodes_crud/form', $data);
	}

	public function update($courseId, $episodeId)
	{
		$post = $this->input->post();
		$data = $this->normalizeEpisodeInput($post);
		$data['episodeID'] = $episodeId;
		$data['videoUri'] = $this->uploadEpisodeVideoIfPresent($courseId, $episodeId, $data['videoUri']);

		// set() to same nested doc id = update/replace
		$response = $this->common->adddatamodelnexted('courses', $courseId, 'Episode', $episodeId, $data);
		if ($response) {
			$this->session->set_flashdata('successmessage', 'Episode updated successfully');
		} else {
			$this->session->set_flashdata('warningmessage', 'Failed to update episode');
		}
		redirect(base_url('episodes/edit/' . $courseId . '/' . $episodeId));
	}

	public function delete($courseId, $episodeId)
	{
		$response = $this->common->nexteddeletedatamodel('courses', $courseId, 'Episode', $episodeId);
		if ($response) {
			$this->session->set_flashdata('successmessage', 'Episode deleted successfully');
		} else {
			$this->session->set_flashdata('warningmessage', 'Failed to delete episode');
		}
		redirect(base_url('episodes/index/' . $courseId));
	}
}

