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

require_once __DIR__ . "/../../lib/requiredpublic.php";

require_once __DIR__ . "/../../lib/Family.lib.php";
require_once __DIR__ . "/../../lib/Child.lib.php";

function errorBack(string $errormsg) {
    header("Location: ../?page=signup&error=" . htmlentities($errormsg));
    die($errormsg);
}

if (empty($_POST['agree_terms'])) {
    errorBack("You must agree to HACHE's policy.");
}

$family = new Family();
$renewal = false;

if (!empty($_SESSION['familyid']) && $database->has("families", ['familyid' => $_SESSION['familyid']])) {
    $family = (new Family())->load($_SESSION['familyid']);
    $renewal = true;
} else if (!empty($_POST['renewing'])) {
    // Session expired, but we're renewing, so kick them back to verification
    header("Location: ../?page=renew&msg=sessionexpired");
    die("You took too long and were automatically logged out.  Please try again.");
}

$database->action(function($database) {
    global $family, $renewal;

    try {
        $lastname = $_POST['familyname'];
        $father = $_POST['fathername'];
        $mother = $_POST['mothername'];

        if (empty($lastname)) {
            errorBack("Enter a last name.");
        }
        if (empty($father)) {
            errorBack("Enter a father name.");
        }
        if (empty($mother)) {
            errorBack("Enter a mother name.");
        }

        $family->setName($lastname);
        $family->setFather($father);
        $family->setMother($mother);

        $family->setPhone($_POST['phone']);
        $family->setEmail($_POST['email']);

        if ($renewal) {
            if ($database->has("families", ["AND" => ["email" => $family->getEmail(), "familyid[!]" => $family->getID()]])) {
                errorBack("That email address is already in use with another family.");
            }
        } else {
            if ($database->has("families", ["email" => $family->getEmail()])) {
                errorBack("That email address is already in use with another family.");
            }
        }

        $address = $_POST['streetaddress'];
        $city = $_POST['city'];
        $state = strtoupper($_POST['state']);
        $zip = $_POST['zip'];
        if (empty($address)) {
            errorBack("Enter a street address.");
        }
        if (empty($city)) {
            errorBack("Enter a city.");
        }
        $family->setAddress($address);
        $family->setCity($city);
        $family->setState($state);
        $family->setZip($zip);


        $newsletter = $_POST['newsletter_method'];
        $membership_cost = 2500;
        if (empty($newsletter)) {
            errorBack("Select a newsletter preference.");
        }
        $family->setNewsletter($newsletter);
        switch ($newsletter) {
            case 1: // Email only
                $membership_cost = 2500;
                break;
            case 2: // Print only
                $membership_cost = 3500;
                break;
            case 3: // Email and print
                $membership_cost = 3500;
                break;
            default:
                errorBack("Select a valid newsletter preference.");
        }

        $photopermission = $_POST['photo_permission'];
        if (!empty($photopermission) && $photopermission == "1") {
            $photopermission = true;
        } else {
            $photopermission = false;
        }
        $family->setPhotoPermission($photopermission);

        $family->save();

        //
        // Children
        //
        $children = $_POST['child'];

        $childObjects = $family->getChildren();

        foreach ($children['ids'] as $cid) {
            if (empty($children['name'][$cid])) {
                continue;
            }

            if (!preg_match("/^([1-9]|1[012])$/", $children['month'][$cid])) {
                errorBack("Invalid birth month chosen for " . htmlentities($children['name'][$cid]) . ".");
            }

            if (!is_numeric($children['year'][$cid])) {
                errorBack("Invalid birth year chosen for " . htmlentities($children['name'][$cid]) . ".");
            }
            $children['year'][$cid] = $children['year'][$cid] * 1;
            if ($children['year'][$cid] < 1980 || $children['year'][$cid] > date("Y")) {
                errorBack("Invalid birth year chosen for " . htmlentities($children['name'][$cid]) . ".");
            }

            if (Child::exists($cid, $family->getID())) {
                // iterate over existing children to find the correct one
                for ($i = 0; $i < count($childObjects); $i++) {
                    if ($childObjects[$i]->getID() == $cid) {
                        $childObjects[$i]->setName($children['name'][$cid]);
                        $childObjects[$i]->setBirthday(null, $children['year'][$cid] . "-" . $children['month'][$cid] . "-00");
                        $childObjects[$i]->setGraduated(empty($children['graduate'][$cid]) ? false : true);
                    }
                }
            } else {
                $child = new Child();
                $child->setName($children['name'][$cid]);
                $child->setBirthday(null, $children['year'][$cid] . "-" . $children['month'][$cid] . "-00");
                $child->setGraduated(empty($children['graduate'][$cid]) ? false : true);
                $child->setFamilyID($family->getID());
                $childObjects[] = $child;
            }
        }

        foreach ($childObjects as $child) {
            $child->save();
        }
    } catch (Exception $ex) {
        errorBack($ex->getMessage());
    }


    //
    // Interests
    //
    $database->delete('interests', ['familyid' => $family->getID()]);
    if (!empty($_POST['events']) && is_array($_POST['events'])) {
        $interests = [];
        foreach ($_POST['events'] as $evt) {
            if ($database->has("events", ['eventid' => $evt])) {
                $interests[] = ["familyid" => $family->getID(), "eventid" => $evt];
            }
        }
        $database->insert("interests", $interests);
    }


    //
    // Payment
    //
    try {
        \Stripe\Stripe::setApiKey(STRIPE_SECKEY);

        $charge = \Stripe\Charge::create([
                    'amount' => $membership_cost,
                    'currency' => 'usd',
                    'description' => 'HACHE Membership',
                    'source' => $_POST['stripeToken'],
                    'statement_descriptor' => 'HACHE Membership 1yr',
        ]);
    } catch (\Stripe\Error\Card $e) {
        $body = $e->getJsonBody();
        $err = $body['error'];
        errorBack("We couldn't process your card because it was declined.  Your card issuer or bank sent us this message: " . $err["message"] . "  That's all we know.");
    } catch (\Stripe\Error\RateLimit $e) {
        errorBack("We couldn't process your card because things are happening too fast.  Please try again in a minute. (Error code: STRIPE_RATELIMIT)");
    } catch (\Stripe\Error\InvalidRequest $e) {
        errorBack("We couldn't process your card because of a technical issue.  Please try again later. (Error code: STRIPE_INVREQ)");
    } catch (\Stripe\Error\Authentication $e) {
        errorBack("We can't connect to the card processor.  Please try again later. (Error code: STRIPE_AUTH)");
    } catch (\Stripe\Error\ApiConnection $e) {
        errorBack("We can't connect to the card processor.  Please try again later. (Error code: STRIPE_NOAPI)");
    } catch (\Stripe\Error\Base $e) {
        errorBack("An unknown payment error occurred.  Please try again later.");
    } catch (Exception $e) {
        errorBack("An unknown error occurred.  Please try again later.");
    }

    $database->insert("payments", [
        "familyid" => $family->getID(),
        "amount" => ($membership_cost / 100.0),
        "paid" => 1,
        "date" => date("Y-m-d H:i:s")
    ]);


    header("Location: ../?page=thanks");
    return true;
});
