<?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/. */

/**
 * Make things happen when buttons are pressed and forms submitted.
 */
require_once __DIR__ . "/required.php";

if ($VARS['action'] !== "signout") {
    dieifnotloggedin();
}

/**
 * Redirects back to the page ID in $_POST/$_GET['source'] with the given message ID.
 * The message will be displayed by the app.
 * @param string $msg message ID (see lang/messages.php)
 * @param string $arg If set, replaces "{arg}" in the message string when displayed to the user.
 */
function returnToSender($msg, $arg = "") {
    global $VARS;
    $header = "Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg";
    if ($arg != "") {
        $header .= "&arg=$arg";
    }
    header($header);
    die();
}

switch ($VARS['action']) {
    case "signout":
        session_destroy();
        header('Location: index.php?logout=1');
        die("Logged out.");
    case "editperson":

        $editing = false;
        $person = [
            "id" => null,
            "familyid" => null,
            "camperid" => null,
            "adultid" => null,
            "youthid" => null,
            "firstname" => "",
            "lastname" => "",
            "address" => "",
            "zip" => "",
            "phone1" => "",
            "phone2" => "",
            "email" => "",
            "unit" => "",
            "shirt" => "",
            "sex" => "",
            "parentname" => "",
            "rank" => "",
            "den" => "",
            "health" => "",
            "notes" => "",
            "child_care" => null,
            "position" => ""
        ];
        if (!empty($VARS['personid']) && $database->has("people", ['personid' => $VARS['personid']])) {
            $person = $database->get('people', ['personid (id)',
                'familyid',
                'camperid',
                'adultid',
                'youthid',
                'firstname',
                'lastname',
                'address',
                'zip',
                'phone1',
                'phone2',
                'email',
                'unit',
                'shirt',
                'sex',
                'notes'], ['personid' => $VARS['personid']]);
            $editing = true;
        }

        function errorBack(string $errormsg) {
            returnToSender($errormsg);
        }

        $database->action(function($database) {
            global $person, $VARS, $editing;

            try {
                if (!empty($VARS['familyid']) && $database->has('families', ['familyid' => $VARS['familyid']])) {
                    $familyid = $VARS['familyid'];
                } else if ($editing) {
                    $familyid = $person['familyid'];
                } else {
                    $database->insert("families", []);
                    $familyid = $database->id();
                }

                $people = array_merge($person, $VARS);

                $requiredfields = [
                    "firstname" => ".+",
                    "lastname" => ".+",
                    "address" => ".+",
                    "zip" => "[0-9]{5}(-?[0-9]{4})?",
                    "phone1" => "[0-9]{10}",
                    "email" => "_EMAIL_",
                    "shirt" => ["NO", "YS", "YM", "YL", "AS", "AM", "AL", "AX", "A2", "A3"],
                    "sex" => ["M", "F"]
                ];

                switch ($people["type"]) {
                    case "camper":
                        $checkfields = array_merge($requiredfields, [
                            "parentname" => ".+",
                            "unit" => "[0-9]{3,4}",
                            "rank" => ["Tiger", "Wolf", "Bear", "Webelos", "Arrow of Light"]
                        ]);
                        break;
                    case "adult":
                        $checkfields = array_merge($requiredfields, [
                            "position" => [
                                "None",
                                "Den Walker",
                                "Station Leader",
                                "Tot Lot",
                                "First Aid",
                                "Floater"
                            ]
                        ]);
                        break;
                    case "youth":
                        $checkfields = array_merge($requiredfields, [
                            "position" => [
                                "None",
                                "Den Chief",
                                "Station",
                                "Tot Lot",
                                "Floater"
                            ],
                            "parentname" => ".+"
                        ]);
                        break;
                    default:
                        errorBack("Invalid person type.");
                }
                foreach ($checkfields as $name => $regex) {
                    $validatefunction = function ($str) use ($regex) {
                        return preg_match("/$regex/", $str);
                    };

                    if (is_array($regex)) {
                        // Array of options
                        $validatefunction = function ($str) use ($regex) {
                            return in_array($str, $regex);
                        };
                    } else if (strpos($regex, "_") === 0) {
                        // Special cases
                        switch ($regex) {
                            case "_EMAIL_":
                                $validatefunction = function ($str) {
                                    return filter_var($str, FILTER_VALIDATE_EMAIL);
                                };
                                break;
                        }
                    }

                    // Validate
                    if (!$validatefunction($people[$name])) {
                        errorBack("Please check your input and try again ($name).");
                    }
                }


                $days = "";
                if (is_string($people["days"])) {
                    $people["days"] = str_split($people["days"], 2);
                }
                if (is_array($people["days"])) {
                    $validdays = ["Tu", "We", "Th", "Fr"];
                    $days = "";
                    foreach ($people["days"] as $day) {
                        if (in_array($day, $validdays)) {
                            $days .= $day;
                        }
                    }
                }

                switch ($people["type"]) {
                    case "camper":
                        $data = [
                            "parentname" => $people["parentname"],
                            "rank" => $people["rank"],
                            "den" => (empty($people["den"]) ? "" : $people["den"]),
                            "health" => (empty($people["health"]) ? "" : $people["health"])
                        ];
                        if ($editing) {
                            $database->update("campers", $data, ['camperid' => $person['camperid']]);
                            $camperid = $person['camperid'];
                        } else {
                            $database->insert("campers", $data);
                            $camperid = $database->id();
                        }
                        break;
                    case "adult":
                        if (!empty($people["child_care"])) {
                            $items = preg_split("/[^\d]+/", $people["child_care"]);
                            $ages = [];
                            foreach ($items as $it) {
                                $ages[] = $it;
                            }
                            $people["child_care"] = implode(",", $ages);
                        }
                        $data = [
                            "position" => $people["position"],
                            "days" => $days,
                            "child_care" => empty($people["child_care"]) ? null : $people["child_care"]
                        ];
                        if ($editing) {
                            $database->update("adults", $data, ['adultid' => $person['adultid']]);
                            $adultid = $person['adultid'];
                        } else {
                            $database->insert("adults", $data);
                            $adultid = $database->id();
                        }
                        break;
                    case "youth":
                        $data = [
                            "position" => $people["position"],
                            "days" => $days,
                            "parentname" => $people["parentname"]
                        ];
                        if ($editing) {
                            $database->update("youth", $data, ['youthid' => $person['youthid']]);
                            $youthid = $person['youthid'];
                        } else {
                            $database->insert("youth", $data);
                            $youthid = $database->id();
                        }
                        break;
                }

                $data = [
                    "familyid" => $familyid,
                    "camperid" => $camperid,
                    "adultid" => $adultid,
                    "youthid" => $youthid,
                    "firstname" => $people["firstname"],
                    "lastname" => $people["lastname"],
                    "address" => $people["address"],
                    "zip" => $people["zip"],
                    "phone1" => empty($people["phone1"]) ? "" : $people["phone1"],
                    "phone2" => empty($people["phone2"]) ? "" : $people["phone2"],
                    "email" => empty($people["email"]) ? "" : $people["email"],
                    "unit" => $people["unit"],
                    "shirt" => $people["shirt"],
                    "sex" => $people["sex"],
                    "notes" => (empty($people["notes"]) ? "" : $people["notes"])
                ];

                if ($editing) {
                    $database->update("people", $data, ['personid' => $VARS['personid']]);
                } else {
                    $database->insert("people", $data);
                }
            } catch (Exception $ex) {
                errorBack($ex->getMessage());
            }
        });

        returnToSender("person_saved", "&id=" . htmlentities($VARS['personid']));
        break;
    case "deleteperson":
        if (!empty($VARS['id']) && $database->count("people", ['personid' => $VARS['id']]) === 1) {
            $ids = $database->get("people", ['camperid', 'adultid', 'youthid'], ['personid' => $VARS['id']]);
            if (!is_null($ids['camperid'])) {
                $database->delete("campers", ['camperid' => $ids['camperid']]);
            } else if (!is_null($ids['adultid'])) {
                $database->delete("adults", ['adultid' => $ids['adultid']]);
            } else if (!is_null($ids['youthid'])) {
                $database->delete("youth", ['youthid' => $ids['youthid']]);
            }
            $database->delete("people", ["personid" => $VARS['id']]);
            returnToSender("person_deleted");
        } else {
            returnToSender("person_doesnt_exist");
        }
        break;
    case "editpayment":
        if (!$database->has("families", ['familyid' => $VARS['familyid']])) {
            returnToSender("invalid_parameters");
        }
        if (!is_numeric($VARS["amount"]) || $VARS["amount"] < 0) {
            returnToSender("invalid_parameters");
        }
        if (!is_numeric($VARS["amountpaid"]) || $VARS["amountpaid"] < 0) {
            returnToSender("invalid_parameters");
        }
        if (empty($VARS['date']) || strtotime($VARS['date']) === false) {
            returnToSender("invalid_parameters");
        }
        if (!empty($VARS['paymentid']) && $database->has("payments", ['paymentid' => $VARS['paymentid']])) {
            $database->update("payments", [
                "familyid" => $VARS["familyid"],
                "amount" => $VARS["amount"],
                "amountpaid" => $VARS["amountpaid"],
                "date" => date("Y-m-d H:i:s", strtotime($VARS['date'])),
                "type" => $VARS["type"]
                    ], [
                "paymentid" => $VARS["paymentid"]
            ]);
            $paymentid = $VARS["paymentid"];
        } else {
            $database->insert("payments", [
                "familyid" => $VARS["familyid"],
                "amount" => $VARS["amount"],
                "amountpaid" => $VARS["amountpaid"],
                "date" => date("Y-m-d H:i:s", strtotime($VARS['date'])),
                "type" => $VARS["type"]
            ]);
            $paymentid = $database->id();
        }
        returnToSender("payment_saved", "&id=$paymentid");
        break;
    case "familysearch":
        $people = $database->select('people', ['familyid (id)', 'firstname', 'lastname'], ['OR' => ['familyid' => $VARS['q'], 'lastname[~]' => $VARS['q'], 'firstname[~]' => $VARS['q']]]);
        $data = [];
        foreach ($people as $p) {
            $data[$p['id']]['names'][] = $p['firstname'] . " " . $p['lastname'];
            $data[$p['id']]['id'] = $p['id'];
        }
        $out = [];
        foreach ($data as $i) {
            $out[] = [
                'id' => $i['id'],
                'name' => implode(", ", $i['names'])
            ];
        }
        header('Content-Type: application/json');
        echo json_encode($out);
}