<?php

require_once __DIR__ . '/BaseController.php';
require_once __DIR__ . '/../models/NewsModel.php';

class NewsController extends BaseController
{

    private $newsModel;

    public function __construct()
    {
        parent::__construct();
        $this->newsModel = new NewsModel();
    }

    /**
     * Get news list with pagination
     */
    public function getNews()
    {
        try {
            $this->allowMethod(['GET']);

            $queryParams = $this->getQueryParams();

            $limit = isset($queryParams['limit']) ? (int) $queryParams['limit'] : 10;
            $offset = isset($queryParams['offset']) ? (int) $queryParams['offset'] : 0;
            $category = $queryParams['category'] ?? null;

            // Validate limit
            if ($limit <= 0 || $limit > 100) {
                $limit = 10;
            }

            // Validate offset
            if ($offset < 0) {
                $offset = 0;
            }

            $news = $this->newsModel->getPublishedNews($limit, $offset, $category);
            $totalNews = $this->newsModel->countPublishedNews($category);

            // Calculate pagination info
            $totalPages = ceil($totalNews / $limit);
            $currentPage = floor($offset / $limit) + 1;
            $hasNext = ($offset + $limit) < $totalNews;
            $hasPrev = $offset > 0;

            Response::success('News retrieved successfully', [
                'news' => $news,
                'pagination' => [
                    'current_page' => $currentPage,
                    'total_pages' => $totalPages,
                    'total_items' => $totalNews,
                    'limit' => $limit,
                    'offset' => $offset,
                    'has_next' => $hasNext,
                    'has_previous' => $hasPrev
                ],
                'filters' => [
                    'category' => $category
                ]
            ]);
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Get news detail by ID
     */
    public function getNewsDetail()
    {
        try {
            $this->allowMethod(['GET']);

            $queryParams = $this->getQueryParams();

            if (!isset($queryParams['id']) || !is_numeric($queryParams['id'])) {
                Response::validationError('News ID is required and must be numeric');
            }

            $id = (int) $queryParams['id'];

            if ($id <= 0) {
                Response::validationError('Invalid news ID');
            }

            $news = $this->newsModel->getNewsById($id);

            if ($news) {
                // Get related news
                $relatedNews = [];
                if ($news['category']) {
                    $relatedNews = $this->newsModel->getRelatedNews($id, $news['category'], 5);
                }

                Response::success('News detail retrieved successfully', [
                    'news' => $news,
                    'related_news' => $relatedNews
                ]);
            } else {
                Response::notFound('News not found or not published');
            }
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Get news categories
     */
    public function getCategories()
    {
        try {
            $this->allowMethod(['GET']);

            $categories = $this->newsModel->getCategories();

            Response::success('Categories retrieved successfully', [
                'categories' => $categories,
                'count' => count($categories)
            ]);
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Get popular news
     */
    public function getPopularNews()
    {
        try {
            $this->allowMethod(['GET']);

            $queryParams = $this->getQueryParams();

            $limit = isset($queryParams['limit']) ? (int) $queryParams['limit'] : 10;
            $category = $queryParams['category'] ?? null;

            // Validate limit
            if ($limit <= 0 || $limit > 50) {
                $limit = 10;
            }

            $popularNews = $this->newsModel->getPopularNews($limit, $category);

            Response::success('Popular news retrieved successfully', [
                'news' => $popularNews,
                'count' => count($popularNews),
                'filters' => [
                    'category' => $category,
                    'limit' => $limit
                ]
            ]);
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Search news
     */
    public function searchNews()
    {
        try {
            $this->allowMethod(['GET']);

            $queryParams = $this->getQueryParams();

            if (!isset($queryParams['q']) || empty(trim($queryParams['q']))) {
                Response::validationError('Search keyword is required');
            }

            $keyword = trim($queryParams['q']);
            $limit = isset($queryParams['limit']) ? (int) $queryParams['limit'] : 10;
            $offset = isset($queryParams['offset']) ? (int) $queryParams['offset'] : 0;

            // Validate parameters
            if ($limit <= 0 || $limit > 100) {
                $limit = 10;
            }

            if ($offset < 0) {
                $offset = 0;
            }

            if (strlen($keyword) < 3) {
                Response::validationError('Search keyword must be at least 3 characters long');
            }

            $news = $this->newsModel->searchNews($keyword, $limit, $offset);

            Response::success('News search completed', [
                'news' => $news,
                'search_params' => [
                    'keyword' => $keyword,
                    'limit' => $limit,
                    'offset' => $offset,
                    'results_count' => count($news)
                ]
            ]);
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Create new news (admin function)
     */
    public function createNews()
    {
        try {
            $this->allowMethod(['POST']);

            $data = $this->getInputData();
            $this->validateRequired($data, ['title', 'content', 'summary', 'author']);

            $newsData = [
                'title' => trim($data['title']),
                'content' => trim($data['content']),
                'summary' => trim($data['summary']),
                'author' => trim($data['author']),
                'category' => trim($data['category'] ?? ''),
                'image_url' => trim($data['image_url'] ?? ''),
                'is_published' => isset($data['is_published']) ? (bool) $data['is_published'] : false,
                'published_at' => $data['published_at'] ?? null
            ];

            // Sanitize data
            $newsData = $this->sanitizeInput($newsData);

            // Validate image URL if provided
            if (!empty($newsData['image_url']) && !filter_var($newsData['image_url'], FILTER_VALIDATE_URL)) {
                Response::validationError('Invalid image URL');
            }

            // Set published_at to now if is_published is true and no published_at is set
            if ($newsData['is_published'] && empty($newsData['published_at'])) {
                $newsData['published_at'] = date('Y-m-d H:i:s');
            }

            $newsId = $this->newsModel->createNews($newsData);

            if ($newsId) {
                Response::success('News created successfully', [
                    'news_id' => $newsId,
                    'message' => 'News article has been created'
                ], 201);
            } else {
                Response::error('Failed to create news');
            }
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Update news (admin function)
     */
    public function updateNews()
    {
        try {
            $this->allowMethod(['POST', 'PUT']);

            $data = $this->getInputData();
            $this->validateRequired($data, ['id']);

            $newsId = (int) $data['id'];

            if ($newsId <= 0) {
                Response::validationError('Invalid news ID');
            }

            // Check if news exists
            if (!$this->newsModel->find($newsId)) {
                Response::notFound('News not found');
            }

            // Prepare update data (only include provided fields)
            $updateData = [];
            $allowedFields = ['title', 'content', 'summary', 'author', 'category', 'image_url', 'is_published', 'published_at'];

            foreach ($allowedFields as $field) {
                if (isset($data[$field])) {
                    $updateData[$field] = trim($data[$field]);
                }
            }

            if (empty($updateData)) {
                Response::validationError('No valid fields provided for update');
            }

            // Sanitize data
            $updateData = $this->sanitizeInput($updateData);

            // Validate image URL if provided
            if (isset($updateData['image_url']) && !empty($updateData['image_url']) && !filter_var($updateData['image_url'], FILTER_VALIDATE_URL)) {
                Response::validationError('Invalid image URL');
            }

            // Set published_at to now if is_published is being set to true and no published_at is provided
            if (isset($updateData['is_published']) && $updateData['is_published'] && !isset($updateData['published_at'])) {
                $updateData['published_at'] = date('Y-m-d H:i:s');
            }

            $result = $this->newsModel->updateNews($newsId, $updateData);

            if ($result) {
                Response::success('News updated successfully');
            } else {
                Response::error('Failed to update news or no changes made');
            }
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Delete news (admin function)
     */
    public function deleteNews()
    {
        try {
            $this->allowMethod(['POST', 'DELETE']);

            $data = $this->getInputData();
            $this->validateRequired($data, ['id']);

            $newsId = (int) $data['id'];

            if ($newsId <= 0) {
                Response::validationError('Invalid news ID');
            }

            // Check if news exists
            if (!$this->newsModel->find($newsId)) {
                Response::notFound('News not found');
            }

            $result = $this->newsModel->delete($newsId);

            if ($result) {
                Response::success('News deleted successfully');
            } else {
                Response::error('Failed to delete news');
            }
        } catch (Exception $e) {
            $this->handleException($e);
        }
    }
}
