<?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 Family {

    private $id;
    private $name = "";
    private $father = "";
    private $mother = "";
    private $phone = "";
    private $email = "";
    private $address = "";
    private $city = "";
    private $state = "";
    private $zip = "";
    private $photo = false;
    private $newsletter = 1;
    private $children = [];

    public function __construct() {

    }

    /**
     * Load a family from the database into this object
     * @global type $database
     * @param int $familyid
     * @return \Family
     * @throws Exception
     */
    public function load(int $familyid): Family {
        global $database;
        if ($database->has("families", ['familyid' => $familyid])) {
            $this->id = $familyid;
        } else {
            throw new Exception("No such family exists.");
        }

        $f = $database->get("families", [
            'familyid (id)',
            'familyname (name)',
            'phone',
            'email',
            'newsletter_method (newsletter)',
            'address',
            'city',
            'state',
            'zip',
            'father_name (father)',
            'mother_name (mother)',
            'photo_permission (photo)'
                ], [
            "familyid" => $this->id
        ]);

        $children = $database->select("people", 'personid', ["familyid" => $this->id]);

        $this->name = $f['name'];
        $this->father = $f['father'];
        $this->mother = $f['mother'];
        $this->phone = $f['phone'];
        $this->email = $f['email'];
        $this->address = $f['address'];
        $this->city = $f['city'];
        $this->state = $f['state'];
        $this->zip = $f['zip'];
        $this->photo = $f['photo'] == 1;
        $this->newsletter = $f['newsletter'];

        foreach ($children as $c) {
            $this->children[] = (new Child())->load($c);
        }

        return $this;
    }

    public function save() {
        global $database;
        if (is_int($this->id) && $database->has("families", ['familyid' => $this->id])) {
            $database->update("families", [
                "familyname" => $this->getName(),
                "father_name" => $this->getFather(),
                "mother_name" => $this->getMother(),
                "phone" => $this->getPhone(),
                "email" => $this->getEmail(),
                "address" => $this->getAddress(),
                "city" => $this->getCity(),
                "state" => $this->getState(),
                "zip" => $this->getZip(),
                "photo_permission" => $this->getPhotoPermission(),
                "newsletter_method" => $this->getNewsletter()
            ], [
                "familyid" => $this->id
            ]);
        } else {
            $database->insert("families", [
                "familyname" => $this->getName(),
                "father_name" => $this->getFather(),
                "mother_name" => $this->getMother(),
                "phone" => $this->getPhone(),
                "email" => $this->getEmail(),
                "address" => $this->getAddress(),
                "city" => $this->getCity(),
                "state" => $this->getState(),
                "zip" => $this->getZip(),
                "photo_permission" => $this->getPhotoPermission(),
                "newsletter_method" => $this->getNewsletter()
            ]);
            $this->id = $database->id();
        }

        for ($i = 0; $i < count($this->children); $i++) {
            $this->children[$i]->setFamilyID($this->id);
            $this->children[$i]->save();
        }
    }

    public function getID() {
        return $this->id;
    }

    public function getName(): string {
        return $this->name;
    }

    public function getFather(): string {
        return $this->father;
    }

    public function getMother(): string {
        return $this->mother;
    }

    public function getPhone(): string {
        return $this->phone;
    }

    public function getEmail(): string {
        return $this->email;
    }

    public function getAddress(): string {
        return $this->address;
    }

    public function getCity(): string {
        return $this->city;
    }

    public function getState(): string {
        return $this->state;
    }

    public function getZip(): string {
        return $this->zip;
    }

    public function getPhotoPermission(): bool {
        return $this->photo == true;
    }

    public function getNewsletter(): int {
        return $this->newsletter;
    }

    public function getChildren(): array {
        return $this->children;
    }



    public function setName(string $name) {
        $this->name = $name;
    }

    public function setFather(string $name) {
        $this->father = $name;
    }

    public function setMother(string $name) {
        $this->mother = $name;
    }

    public function setPhone(string $phone) {
        $phone = preg_replace("/[^0-9]/", "", $phone);
        if (strlen($phone) == 11) {
            $phone = preg_replace("/^1/", "", $phone);
        }
        if (strlen($phone) != 10) {
            throw new Exception("Enter a valid 10-digit phone number.");
        }
        $this->phone = $phone;
    }

    public function setEmail(string $email) {
        $email = strtolower($email);
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new Exception("The email address looks wrong.");
        }
        $this->email = $email;
    }

    public function setAddress(string $address) {
        $this->address = $address;
    }

    public function setCity(string $city) {
        $this->city = $city;
    }

    /**
     * Set the state, in two-character form.
     * @param string $state
     * @throws Exception
     */
    public function setState(string $state) {
        $state = strtoupper($state);
        if (!preg_match("/^[A-Z]{2}$/", $state)) {
            throw new Exception("Select a valid state.");
        }
        $this->state = strtoupper($state);
    }

    public function setZip(string $zip) {
        if (!preg_match("/^[0-9]{5}(-?[0-9]{4})?$/", $zip)) {
            throw new Exception("Enter a valid five or nine digit US ZIP code.");
        }
        $this->zip = $zip;
    }

    public function setPhotoPermission(bool $perm) {
        $this->photo = $perm;
    }

    public function setNewsletter(int $newsletter) {
        if (!is_int($newsletter) || !($newsletter == 1 || $newsletter == 2 || $newsletter == 3)) {
            throw new Exception("Invalid newsletter preference.");
        }
        $this->newsletter = $newsletter;
    }

    public function setChildren(array $children) {
        $this->children = $children;
    }

    public function addChild(Child $child) {
        $this->children[] = $child;
    }

}
