<?php
header('Access-Control-Allow-Origin: https://localhost:4200');

header('Access-Control-Allow-Methods: GET, POST');

header("Access-Control-Allow-Headers: X-Requested-With");

header('Access-Control-Allow-Credentials: true');

class DBConnection
{
    private string $host = '127.0.0.1';
    private string $database = 'NewsDb';
    private string $user = 'root';
    private string $password = '';
    private string $charset = 'UTF8';

    # used php data objects (PDO) to connect to database
    private PDO $pdo;
    private string $error;

    public function __construct()
    {
        $dsn = "mysql:host=$this->host;dbname=$this->database;charset=$this->charset";
        #  array of options that configures the PDO object
        $opt = array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, # if a database error occurs, PDO will throw a PDOException instead of just returning false or null
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, # when you fetch rows from a query result set, PDO will return an associative array where the keys are the column names and the values are the column values
            PDO::ATTR_EMULATE_PREPARES => false
        ); # emulation is disabled, PDO uses real prepared statements instead (no substituting parameters into the SQL statement.)
        try {
            $this->pdo = new PDO($dsn, $this->user, $this->password, $opt);
        } catch (PDOException $e) {
            $this->error = $e->getMessage();
            echo "Error connecting to database: " . $this->error;
        }
    }

    public function getAllNews()
    {
        // $statement = $this->pdo->query("SELECT * FROM logs");
        $statement = $this->pdo->prepare("SELECT * FROM News");
        $statement->execute();
        return $statement->fetchAll(PDO::FETCH_ASSOC);
    }

    public function getAllNewsByDate($date)
    {
        if (!empty($date)) {
            $statement = $this->pdo->prepare("SELECT * FROM News WHERE date = ?");
            $statement->execute([$date]);
            return $statement->fetchAll(PDO::FETCH_ASSOC);
        }
        http_response_code(400);
    }
    public function getAllNewsByCategory($category)
    {
        if (!empty($category)) {
            $statement = $this->pdo->prepare("SELECT * FROM News WHERE category = ?");
            $statement->execute([$category]);
            return $statement->fetchAll(PDO::FETCH_ASSOC);
        }
        http_response_code(400);
    }
    public function getAllNewsByCategoryAndDate($category, $date)
    {
        if (!empty($category) && !empty($date)) {
            $statement = $this->pdo->prepare("SELECT * FROM News WHERE category = ? AND date = ?");
            $statement->execute([$category, $date]);
            return $statement->fetchAll(PDO::FETCH_ASSOC);
        }
        if (!empty($category) && empty($date)) {
            return $this->getAllNewsByCategory($category);
        }
        if (empty($category) && !empty($date)) {
            return $this->getAllNewsByDate($date);
        }
        http_response_code(400);
    }

    public function validateUser($username, $password)
    {
        if (!empty($username) && !empty($password)) {
            $statement = $this->pdo->prepare("SELECT 1 FROM Users WHERE username = ? AND password = ?");
            $statement->execute([$username, $password]);
            return $statement->fetchAll(PDO::FETCH_ASSOC);
        }
        http_response_code(400);
    }

    public function insertNews($title, $news_text, $category, $date, $producer)
    {
        if (!empty($title) && !empty($news_text) && !empty($category) && !empty($date) && !empty($producer)) {
            $statement = $this->pdo->prepare("INSERT INTO News (title, news_text, category, date, producer) VALUES (?, ?, ?, ?, ?)");
            $statement->execute([$title, $news_text, $category, $date, $producer]);
            return $statement->rowCount();
        }
        http_response_code(400);
    }

    public function updateNews($id, $title, $news_text, $category, $date, $producer)
    {
        if (!empty($id) && !empty($title) && !empty($news_text) && !empty($category) && !empty($date)) {
            $statement = $this->pdo->prepare("UPDATE News SET title = ?, news_text = ?, category = ?, date = ?, producer = ? WHERE id = ?");
            $statement->execute([$title, $news_text, $category, $date, $producer, $id]);
            return $statement->rowCount();
        }
        http_response_code(400);
    }

    public function getNewsById($id)
    {
        if (!empty($id)) {
            $statement = $this->pdo->prepare("SELECT * FROM News WHERE id = ?");
            $statement->execute([$id]);
            return $statement->fetch(PDO::FETCH_ASSOC);
        }
        http_response_code(400);
    }

    public function show($value)
    {
        echo json_encode($value);
    }

    public function handleGet()
    {
        if (isset($_GET['action']) && !empty($_GET['action'])) {
            switch ($_GET['action']) {
                case 'getAllNews':
                    session_start();
                    $result = $this->getAllNews();
                    $this->show($result);
                    break;
                case 'getAllNewsByCategory':
                    session_start();
                    $category = $_GET['category'];
                    $result = $this->getAllNewsByCategory($category);
                    $this->show($result);
                    break;
                case 'getAllNewsByCategoryAndDate':
                    session_start();
                    $category = $_GET['category'];
                    $date = $_GET['date'];
                    $result = $this->getAllNewsByCategoryAndDate($category, $date);
                    $this->show($result);
                    break;
                case 'getAllNewsByDate':
                    session_start();
                    $date = $_GET['date'];
                    $result = $this->getAllNewsByDate($date);
                    $this->show($result);
                    break;
                case 'validateUser':
                    session_start();
                    $username = $_GET['username'];
                    $password = $_GET['password'];
                    $result = $this->validateUser($username, $password);
                    $this->show($result);
                    break;
                case 'getNewsById':
                    session_start();
                    $id = $_GET['id'];
                    $result = $this->getNewsById($id);
                    $this->show($result);
                    break;
                case 'isLogged':
                    $this->show(true);
                    break;
                case 'logout':
                    session_start();
                    session_unset();
                    //session_destroy();
                    $this->show($_SESSION);
                    break;
            }
        }
    }
    public function handlePost()
    {
        if (isset($_POST['action']) && !empty($_POST['action'])) {
            switch ($_POST['action']) {
                case 'insertNews':
                    session_start();

                    $title = $_POST['title'];
                    $news_text = $_POST['news_text'];
                    $category = $_POST['category'];
                    $producer = $_POST['producer'];
                    $date = $_POST['date'];
                    $result = $this->insertNews($title, $news_text, $category, $date, $producer);

                    $this->show($result);
                    break;
                case 'updateNews':
                    session_start();
                    $id = $_POST['id'];
                    $title = $_POST['title'];
                    $news_text = $_POST['news_text'];
                    $category = $_POST['category'];
                    $date = $_POST['date'];
                    $producer = $_POST['producer'];
                    $result = $this->updateNews($id, $title, $news_text, $category, $date, $producer);
                    $this->show($result);
                    break;
            }
        }
    }

    public function handleLogin()
    {
        if (isset($_POST['action']) && !empty($_POST['action']) && $_POST['action'] == 'validateUser') {
            session_start();
            $username = $_POST['username'];
            $password = $_POST['password'];
            $result = $this->validateUser($username, $password);
            if (!empty($result)) {
                $_SESSION['username'] = $username;
                $this->show($result);
            } else {
                http_response_code(401);
            }
        }
        if (isset($_GET['action']) && !empty($_GET['action']) && $_GET['action'] == 'isLogged') {
            $this->show(false);
        }
        if (isset($_GET['action']) && !empty($_GET['action'])) {
            switch ($_GET['action']) {
                case 'getAllNews':
                    session_start();
                    $result = $this->getAllNews();
                    $this->show($result);
                    break;
                case 'getAllNewsByCategory':
                    session_start();
                    $category = $_GET['category'];
                    $result = $this->getAllNewsByCategory($category);
                    $this->show($result);
                    break;
                case 'getAllNewsByCategoryAndDate':
                    session_start();
                    $category = $_GET['category'];
                    $date = $_GET['date'];
                    $result = $this->getAllNewsByCategoryAndDate($category, $date);
                    $this->show($result);
                    break;
                case 'getAllNewsByDate':
                    session_start();
                    $date = $_GET['date'];
                    $result = $this->getAllNewsByDate($date);
                    $this->show($result);
                    break;
                case 'validateUser':
                    session_start();
                    $username = $_GET['username'];
                    $password = $_GET['password'];
                    $result = $this->validateUser($username, $password);
                    $this->show($result);
                    break;
                case 'getNewsById':
                    session_start();
                    $id = $_GET['id'];
                    $result = $this->getNewsById($id);
                    $this->show($result);
                    break;
            }
        }

    }
}
$conn = new DBConnection();
session_start();
if (isset($_SESSION['username'])) {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $conn->handlePost();
    } else {
        $conn->handleGet();
    }
} else {
    $conn->handleLogin();
}
?>