<?php

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

class Event implements JsonSerializable {

    private $id = "";
    private $event = [];
    private $exists = false;

    public function __construct($eventid) {
        global $database;
        $this->id = $eventid;
        if (\Event::exists($eventid)) {
            $this->exists = true;
            $this->event = $database->get('events', ['machineid', 'eventname', 'eventid', 'techuid', 'date', 'privatenotes', 'publicnotes'], ['historyid' => $eventid]);
        }
    }

    public static function create(string $machineid = "", string $date = "", string $event = "", string $techuid = "", string $publicnotes = "", string $privatenotes = ""): Event {
        if ($machineid == "" || $date == "" || empty($event)) {
            return new Event("");
        } else {
            if (!Machine::exists($machineid)) {
                throw new Exception("Invalid machine ID $machineid");
            }
            if (strtotime($date) === false) {
                throw new Exception("Invalid date.");
            }
            $date = date("Y-m-d H:i:s", strtotime($date));

            $evt = new Event("");

            $evt->setMachineID($machineid);
            $evt->setName($event);
            $evt->setDate($date);
            $evt->setTechUID($techuid);
            $evt->setPrivateNotes($privatenotes);
            $evt->setPublicNotes($publicnotes);
            $evt->save();

            return $evt;
        }
    }

    public static function exists($id): bool {
        global $database;
        return $database->has('events', ['historyid' => $id]);
    }

    public static function getTypes() {
        $list = json_decode(file_get_contents(__DIR__ . '/../custom/events.json'), true);

        return $list;
    }

    public static function getFormDataArray() {
        return [
            "types" => $this->getTypes(),
            "inputtypes" => [
                "machineid" => "text",
                "name" => "select",
                "date" => "datetime",
                "privatenotes" => "textarea",
                "publicnotes" => "textarea"
            ],
            "labels" => [
                "machineid" => $Strings->get("Machine ID", false),
                "name" => $Strings->get("Event", false),
                "date" => $Strings->get("Date", false),
                "privatenotes" => $Strings->get("Private Notes", false),
                "publicnotes" => $Strings->get("Public Notes", false)
            ],
            "icons" => []
        ];
    }

    public static function getTypesFormattedForForm() {
        $eventtypes = Event::getTypes();
        $eventselect = [];
        foreach ($eventtypes as $key => $val) {
            $optgroup = trim(str_replace("[]", "", $key));
            $valprepend = strpos($key, " []") !== false ? "" : trim($key);
            foreach ($val as $v) {
                if (empty($valprepend)) {
                    $vpre = "";
                } else if (empty($v)) {
                    $vpre = $valprepend;
                } else {
                    $vpre = $valprepend . ": ";
                }
                if (empty($v)) {
                    $eventselect[$optgroup][$vpre] = "[$vpre Other]";
                } else {
                    $eventselect[$optgroup][$vpre . $v] = $v;
                }
            }
        }
        return $eventselect;
    }

    public function toArray() {
        global $Strings;
        if ($this->exists) {
            return [
                "id" => $this->getID(),
                "machineid" => $this->getMachineID(),
                "name" => $this->getName(),
                "date" => strtotime($this->getDate()),
                "techuid" => $this->getTechUID(),
                "publicnotes" => $this->getPublicNotes(),
                "privatenotes" => $this->getPrivateNotes()
            ];
        }
        return [];
    }

    /**
     * Render the events's info to HTML
     * @param bool $public
     */
    public function toHTML(bool $public = true): string {
        global $Strings, $SETTINGS;

        $html = $Strings->build("event html label", [
            "name" => $this->getName(),
            "date" => date($SETTINGS["datetime_format"], strtotime($this->getDate()))
        ], false);
        $html .= "<br>\n";
        if (!empty($this->getTechUID()) && $public == false) {
            $html .= "<b>" . $Strings->get("Technician", false) . ":</b> " . htmlspecialchars((new User($this->getTechUID()))->getName()) . "<br>\n";
        }
        if (!empty($this->getPublicNotes())) {
            $html .= "<div><b>" . ($public ? $Strings->get("Notes", false) : $Strings->get("Public Notes", false)) . ":</b><br><div class=\"ml-3\">" . htmlspecialchars($this->getPublicNotes()) . "</div></div>";
        }
        if (!empty($this->getPrivateNotes()) && $public == false) {
            $html .= "<div><b>" . $Strings->get("Private Notes", false) . ":</b><br><div class=\"ml-3\">" . htmlspecialchars($this->getPrivateNotes()) . "</div></div>";
        }
        return $html;
    }

    public function jsonSerialize() {
        return $this->toArray();
    }

    private static function getLegacyTypes() {
        global $database;
        $types = $database->select("event_types", ["eventid (id)", "eventname (name)"]);

        $list = [];
        foreach ($types as $t) {
            $list[$t['id']] = $t['name'];
        }
        return $list;
    }

    public function save() {
        global $database;
        if ($this->exists) {
            $database->update("events", $this->event, ["historyid" => $this->id]);
        } else {
            $database->insert("events", $this->event);
            $this->id = $database->id();
            $this->exists = true;
        }
    }

    public function getID(): string {
        return $this->id . "";
    }

    public function getMachineID(): string {
        if (!empty($this->event["machineid"])) {
            return $this->event["machineid"];
        }
        return "";
    }

    public function getName(): string {
        if (!empty($this->event["eventname"])) {
            return $this->event["eventname"];
        } else if (!empty($this->event["eventid"])) {
            return self::getLegacyTypes()[$this->event["eventid"]];
        }
        return "Other";
    }

    public function getDate(): string {
        if (!empty($this->event["date"])) {
            return $this->event["date"];
        }
        return "";
    }

    public function getTechUID(): string {
        if (!empty($this->event["techuid"])) {
            return $this->event["techuid"];
        }
        return "";
    }

    public function getPublicNotes(): string {
        if (!empty($this->event["publicnotes"])) {
            return $this->event["publicnotes"];
        }
        return "";
    }

    public function getPrivateNotes(): string {
        if (!empty($this->event["privatenotes"])) {
            return $this->event["privatenotes"];
        }
        return "";
    }

    public function setMachineID($id) {
        $this->event["machineid"] = $id;
    }

    public function setName(string $name) {
        $this->event["eventname"] = $name;
    }

    public function setTechUID($uid) {
        $this->event["techuid"] = $uid;
    }

    public function setDate(string $date) {
        $this->event["date"] = date("Y-m-d H:i:s", strtotime($date));
    }

    public function setPrivateNotes(string $notes) {
        $this->event["privatenotes"] = $notes;
    }

    public function setPublicNotes(string $notes) {
        $this->event["publicnotes"] = $notes;
    }

}
