<?php

/*
 * Copyright 2019 Netsyms Technologies.
 * 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/.
 */

use InvoiceNinja\Config as NinjaConfig;
use InvoiceNinja\Models\Client as NinjaClient;

class Client {

    private $local = true;
    private $exists = false;
    private $full = true;
    private $id = "";
    private $name = "";
    private $phone = "";
    private $email = "";
    private $billingaddress = "";
    private $mailingaddress = "";
    private $publicnotes = "";
    private $privatenotes = "";

    /**
     *
     * @param type $id
     * @param type $local
     * @param type $full
     * @param type $name
     */
    public function __construct($id = "", $local = true, $name = "") {
        global $database;
        if (!empty($id)) {
            $this->id = $id;
            $this->local = $local;
            $this->exists = true;
            if ($local) {
                $this->full = true;
                $data = $database->get("clients", ['name', 'phone', 'email', 'billingaddress', 'mailingaddress', 'publicnotes', 'privatenotes'], ["clientid" => $id]);
                $this->setName($data['name'] . "");
                $this->setPhone($data['phone'] . "");
                $this->setEmail($data['email'] . "");
                $this->setBillingAddress($data['billingaddress'] . "");
                $this->setMailingAddress($data['mailingaddress'] . "");
                $this->setPublicNotes($data['publicnotes'] . "");
                $this->setPrivateNotes($data['privatenotes'] . "");
            } else {
                $this->full = false;
                $this->name = $name;
            }
        }
    }

    /**
     * Fill in all the client data from the InvoiceNinja API.
     */
    private function fullerize() {
        global $SETTINGS;
        if (!$this->local && !$this->full && $this->exists) {
            try {
                $client = NinjaClient::find($this->id);
                $this->full = true;
                // Name
                $this->setName($client->display_name);
                // Phone
                if (!empty($client->work_phone)) {
                    $this->setPhone($client->work_phone);
                } else if (!empty($client->contacts[0]->phone)) {
                    $this->setPhone($client->contacts[0]->phone);
                }
                if (!empty($client->contacts[0]->email)) {
                    $this->setEmail($client->contacts[0]->email);
                }
                $billingaddress = [
                    $client->address1,
                    $client->address2,
                    implode(" ", array_filter([$client->city, $client->state, $client->postal_code]))
                ];
                $this->setBillingAddress(implode("\n", array_filter($billingaddress)));

                $mailingaddress = [
                    $client->shipping_address1,
                    $client->shipping_address2,
                    implode(" ", array_filter([$client->shipping_city, $client->shipping_state, $client->shipping_postal_code]))
                ];
                $this->setMailingAddress(implode("\n", array_filter($mailingaddress)));

                $this->setPublicNotes($client->public_notes);
                $this->setPrivateNotes($client->private_notes);
            } catch (Exception $ex) {
                if ($SETTINGS['debug']) {
                    echo $ex->getTraceAsString();
                }
                sendError("Unable to query client from InvoiceNinja server:\n" . $ex->getMessage());
            }
        }
    }

    public static function exists($id, $local = true): bool {
        global $database, $SETTINGS;
        if ($local) {
            return $database->has('clients', ['clientid' => $id]);
        }
        try {
            $client = NinjaClient::find($id);
            return true;
        } catch (Exception $ex) {
            if ($ex->getMessage() == "{\n    \"message\": \"record does not exist\"\n}") {
                return false;
            }
            if ($SETTINGS['debug']) {
                echo $ex->getTraceAsString();
            }
            sendError("Unable to query client ID from InvoiceNinja server:\n" . $ex->getMessage());
        }
    }

    /**
     * Save the client.
     */
    public function save() {
        global $database;
        if ($this->isLocal()) {
            $data = [
                "name" => $this->getName(),
                "phone" => $this->getPhone(),
                "email" => $this->getEmail(),
                "billingaddress" => $this->getBillingAddress(),
                "mailingaddress" => $this->getMailingAddress(),
                "publicnotes" => $this->getPublicNotes(),
                "privatenotes" => $this->getPrivateNotes()
            ];
            if (!empty($this->id) && $database->has("clients", ["clientid" => $this->id])) {
                $database->update("clients", $data, ["clientid" => $this->id]);
            } else {
                $database->insert("clients", $data);
                $this->id = $database->id();
            }
            return;
        }

        if ($this->exists) {
            $client = NinjaClient::find($id);
            $client->name = $this->getName();
        } else {
            $client = new NinjaClient($this->getEmail(), '', '', $this->getName());
        }
        $client->work_phone = $this->getPhone();
        $client->public_notes = $this->getPublicNotes();
        $client->private_notes = $this->getPrivateNotes();
        $client->save();
    }

    public function isLocal(): bool {
        return $this->local;
    }

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

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

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

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

    public function getBillingAddress(): string {
        $this->fullerize();
        return $this->billingaddress;
    }

    public function getMailingAddress(): string {
        $this->fullerize();
        return $this->mailingaddress;
    }

    public function getPublicNotes(): string {
        $this->fullerize();
        return $this->publicnotes;
    }

    public function getPrivateNotes(): string {
        $this->fullerize();
        return $this->privatenotes;
    }

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

    public function setPhone(string $phone) {
        $this->fullerize();
        $this->phone = $phone;
    }

    public function setEmail(string $email) {
        $this->fullerize();
        $this->email = $email;
    }

    public function setBillingAddress(string $address) {
        $this->fullerize();
        $this->billingaddress = $address;
    }

    public function setMailingAddress(string $address) {
        $this->fullerize();
        $this->mailingaddress = $address;
    }

    public function setPublicNotes(string $notes) {
        $this->fullerize();
        $this->publicnotes = $notes;
    }

    public function setPrivateNotes(string $notes) {
        $this->fullerize();
        $this->privatenotes = $notes;
    }

}
