<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Hash;
use Validator;
use App\Responses;
use App\Helper;
use App\Models\Clients;
use App\Models\Users;
use App\Models\UserLogs;
use Auth;

class ClientController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function view_clients()
    {
        $data = [
            "disc_types" => Clients::select2DiscountTypes(),
        ];

		$log = [
			"module" => "Company",
			"action" => "View",
			"desc" => "Open Company Menu",
		];
		UserLogs::insert(Auth::user()->id, $log);
        return view("menu_v1.clients", $data);
    }

    /**
     * API
     */

    public function api_list_clients(Request $req)
    {
        try {
            $now = time();
            $input = [];
            $rulesInput = [];

            // validasi input
            // $isValidInput = Validator::make($input, $rulesInput);
            // if (!$isValidInput->passes()) {
            // 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
            // 	return new Response($apiResp, $apiResp['meta']['code']);
            // }

            $filter = [];
            if ($req->cptid) {
                $filter["company"] = $req->cptid;
            }
            $list = Clients::listClients($filter);
            foreach ($list as $key => $row) {
                $list[$key]->DT_RowIndex = $key + 1;
                // $list[$key]->count_trx = 0;
            }

            $apiResp = Responses::success("success list clients");
            $apiResp["data"] = $list;
            $apiResp["count"] = count($list);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_show_client(Request $req, $cid)
    {
        try {
            $now = time();

            $input = [
                "cid" => $cid,
            ];
            $rulesInput = [
                "cid" => "required|integer|not_in:0",
            ];

            // validasi input
            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $client = Clients::showClientById($cid);
            if (count($client) < 1) {
                $apiResp = Responses::not_found("client not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($client[0]->user_id) {
                $client[0]->c_credentials = Clients::CCREDENTIALS_CREATE;
            } else {
                $client[0]->c_credentials = Clients::CCREDENTIALS_NOT;
            }

            $apiResp = Responses::success("success get detail client");
            $apiResp["data"] = $client[0];
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_add_client(Request $req)
    {
        //dd($req->all());
        $url_clogo = "";

        try {
            $now = time();

            $input = [
                "client_logo" => $req->clogo_base64,
                "client_name" => $req->cname,
                "client_office_address" => $req->caddress_office,
                "client_phone" => $req->cphone,
                "client_email" => $req->cmail,
                "pic_name" => $req->picname,
                "pic_phone" => $req->picphone,
                "pic_email" => $req->picmail,
                // "disc_type" => $req->disc_type,
                // "disc_amount" => $req->disc_amount,
                "client_status" => $req->cstatus,
                "is_create_login_credentials" => $req->ccredentials,
            ];
            $rulesInput = [
                "client_logo" => "required|string",
                "client_name" => "required|string|max:255",
                "client_office_address" => "required|string|min:45|max:300",
                "client_phone" => "required|integer|not_in:0",
                "client_email" => "required|string|email",
                "pic_name" => "required|string|max:255",
                "pic_phone" => "required|integer|not_in:0",
                "pic_email" => "required|string|email",
                // "disc_type" => "required|numeric|min:0",
                // "disc_amount" => "required|numeric|min:0",
                "client_status" => "required|numeric",
                "is_create_login_credentials" => "required|numeric",
            ];

            // validasi input
            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $uniqCPhone = Clients::getClientByPhone($req->cphone);
            if (count($uniqCPhone) > 0) {
                $apiResp = Responses::bad_request("client phone has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $uniqCMail = Clients::getClientByEmail($req->cmail);
            if (count($uniqCMail) > 0) {
                $apiResp = Responses::bad_request("client email has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $uniqPicPhone = Clients::getPicByPhone($req->picphone);
            if (count($uniqPicPhone) > 0) {
                $apiResp = Responses::bad_request("pic phone has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $uniqPicMail = Clients::getPicByEmail($req->picmail);
            if (count($uniqPicMail) > 0) {
                $apiResp = Responses::bad_request("pic email has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $uniqUserPhone = Users::getUserByPhone($req->cphone);
            if (count($uniqUserPhone) > 0) {
                $apiResp = Responses::bad_request("client phone has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $uniqUserMail = Users::getUserByEmail($req->cmail);
            if (count($uniqUserMail) > 0) {
                $apiResp = Responses::bad_request("client email has been used");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->disc_type == Clients::DISC_TYPE_PERCENT && $req->disc_amount > 100) {
                $apiResp = Responses::bad_request("maximum percent is 100%");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            DB::beginTransaction();

            $insClient = [
                "c_name" => $req->cname,
                "c_addr_office" => $req->caddress_office,
                "c_phone" => $req->cphone,
                "c_phone_code" => Clients::DEFAULT_PHONE_CODE,
                "c_mail" => $req->cmail,
                "c_logo" => $url_clogo,
                "pic_name" => $req->picname,
                "pic_phone" => $req->picphone,
                "pic_phone_code" => Clients::DEFAULT_PHONE_CODE,
                "pic_mail" => $req->picmail,
                "disc_type" => 0,
                "disc_amount" => 0,
                "c_status" => $req->cstatus,
                "crt" => $now,
                "crt_by" => $req->auth->uid,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ];
            $clientId = Clients::addClient($insClient);

            $url_clogo = "clients/$clientId/logo_$now.jpeg";
            if (!Storage::disk("public")->put($url_clogo, base64_decode($req->clogo_base64))) {
                DB::rollBack();
                $apiResp = Responses::bad_request("fail upload client logo");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }
            $updtClient = [
                "c_logo" => $url_clogo,
            ];
            Clients::updateClient($clientId, $updtClient);

            if ($req->ccredentials == Clients::CCREDENTIALS_CREATE) {
                $status = Users::STATUS_ACTIVE;
                if ($req->cstatus == Clients::CSTTS_INACTIVE) {
                    $status = Users::STATUS_NOT_ACTIVE;
                }
                $insAccount = [
                    "client_id" => $clientId,
                    "client_group_id" => $clientId,
                    "first_name" => $req->cname,
                    "last_name" => null,
                    "email" => $req->cmail,
                    "phone" => $req->cphone,
                    "phone_code" => Users::DEFAULT_PHONE_CODE,
                    "fulladdress" => $req->caddress_office,
                    "password" => Hash::make($req->cphone),
                    "role" => Users::ROLE_VENDOR,
                    "status" => $status,
                    "crt" => $now,
                    "crt_by" => $req->auth->uid,
                    "updt" => $now,
                    "updt_by" => $req->auth->uid,
                ];
                Users::addUser($insAccount);
            }

            $apiResp = Responses::created("success add new client");

            DB::commit();

			$log = [
				"module" => "Company",
				"action" => "Create",
				"desc" => "Add new company: ".$req->cname,
			];
			UserLogs::insert(Auth::user()->id, $log);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            Storage::disk("public")->delete($url_clogo);
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_edit_client(Request $req, $cid)
    {
        $url_clogo = "";

        try {
            $now = time();

            $input = [
                "cid" => $cid,
                "client_logo" => $req->clogo_base64,
                "client_name" => $req->cname,
                "client_office_address" => $req->caddress_office,
                "client_phone" => $req->cphone,
                "client_email" => $req->cmail,
                "pic_name" => $req->picname,
                "pic_phone" => $req->picphone,
                "pic_email" => $req->picmail,
                "disc_type" => $req->disc_type,
                "disc_amount" => $req->disc_amount,
                "client_status" => $req->cstatus,
                "is_create_login_credentials" => $req->ccredentials,
            ];
            $rulesInput = [
                "cid" => "required|integer|not_in:0",
                "client_logo" => "required|string",
                "client_name" => "required|string|max:255",
                "client_office_address" => "required|string|min:45|max:300",
                "client_phone" => "required|integer|not_in:0",
                "client_email" => "required|string|email",
                "pic_name" => "required|string|max:255",
                "pic_phone" => "required|integer|not_in:0",
                "pic_email" => "required|string|email",
                // "disc_type" => "required|numeric|min:0",
                // "disc_amount" => "required|numeric|min:0",
                "client_status" => "required|numeric",
                "is_create_login_credentials" => "required|numeric",
            ];

            // validasi input
            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $client = Clients::showClientById($cid);
            if (count($client) < 1) {
                $apiResp = Responses::not_found("client not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $uniqCPhone = Clients::getClientByPhone($req->cphone);
            if (count($uniqCPhone) > 0) {
                $notSameUser = 1;
                foreach ($uniqCPhone as $key => $row) {
                    if ($row->id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("client phone has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            $uniqCMail = Clients::getClientByEmail($req->cmail);
            if (count($uniqCMail) > 0) {
                $notSameUser = 1;
                foreach ($uniqCMail as $key => $row) {
                    if ($row->id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("client email has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            $uniqPicPhone = Clients::getPicByPhone($req->picphone);
            if (count($uniqPicPhone) > 0) {
                $notSameUser = 1;
                foreach ($uniqPicPhone as $key => $row) {
                    if ($row->id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("pic phone has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            $uniqPicMail = Clients::getPicByEmail($req->picmail);
            if (count($uniqPicMail) > 0) {
                $notSameUser = 1;
                foreach ($uniqPicMail as $key => $row) {
                    if ($row->id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("pic email has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            $uniqUserPhone = Users::getUserByPhone($req->cphone);
            if (count($uniqUserPhone) > 0) {
                $notSameUser = 1;
                foreach ($uniqUserPhone as $key => $row) {
                    if ($row->client_group_id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("client phone has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }
            $uniqUserMail = Users::getUserByEmail($req->cmail);
            if (count($uniqUserMail) > 0) {
                $notSameUser = 1;
                foreach ($uniqUserMail as $key => $row) {
                    if ($row->client_group_id == $cid) {
                        $notSameUser = 0;
                    }
                }
                if ($notSameUser) {
                    $apiResp = Responses::bad_request("client email has been used");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
            }

            if ($req->disc_type == Clients::DISC_TYPE_PERCENT && $req->disc_amount > 100) {
                $apiResp = Responses::bad_request("maximum percent is 100%");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $user = Users::getUserByClientId($cid);

            DB::beginTransaction();

            $url_clogo = $client[0]->c_logo;
            if ($req->clogo_base64 && $req->clogo_base64 != "noupdate") {
                $url_clogo = "clients/$cid/logo_$now.jpeg";
                if (!Storage::disk("public")->put($url_clogo, base64_decode($req->clogo_base64))) {
                    DB::rollBack();
                    $apiResp = Responses::bad_request("fail upload client logo");
                    return new Response($apiResp, $apiResp["meta"]["code"]);
                }
                Storage::disk("public")->delete($client[0]->c_logo);
            }

            $updtClient = [
                "c_name" => $req->cname,
                "c_addr_office" => $req->caddress_office,
                "c_phone" => $req->cphone,
                "c_phone_code" => Clients::DEFAULT_PHONE_CODE,
                "c_mail" => $req->cmail,
                "c_logo" => $url_clogo,
                "pic_name" => $req->picname,
                "pic_phone" => $req->picphone,
                "pic_phone_code" => Clients::DEFAULT_PHONE_CODE,
                "pic_mail" => $req->picmail,
                "disc_type" => $req->disc_type,
                "disc_amount" => $req->disc_amount,
                "c_status" => $req->cstatus,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ];
            Clients::updateClient($cid, $updtClient);

            if ($req->ccredentials == Clients::CCREDENTIALS_CREATE && count($user) < 1) {
                $status = Users::STATUS_ACTIVE;
                if ($req->cstatus == Clients::CSTTS_INACTIVE) {
                    $status = Users::STATUS_NOT_ACTIVE;
                }
                $insAccount = [
                    "client_id" => $cid,
                    "client_group_id" => $cid,
                    "first_name" => $req->cname,
                    "last_name" => null,
                    "email" => $req->cmail,
                    "phone" => $req->cphone,
                    "phone_code" => Users::DEFAULT_PHONE_CODE,
                    "fulladdress" => $req->caddress_office,
                    "password" => Hash::make($req->cphone),
                    "role" => Users::ROLE_CLIENT_ADMIN,
                    "status" => $status,
                    "crt" => $now,
                    "crt_by" => $req->auth->uid,
                    "updt" => $now,
                    "updt_by" => $req->auth->uid,
                ];
                Users::addUser($insAccount);
            }

            $status = Users::STATUS_ACTIVE;
            if ($req->cstatus == Clients::CSTTS_INACTIVE) {
                $status = Users::STATUS_NOT_ACTIVE;
            }

            // update the client credentials only
            if (count($user) > 0) {
                $updtAccount = [
                    "status" => $status,
                    "updt" => $now,
                    "updt_by" => $req->auth->uid,
                ];
                Users::UpdateUser($user[0]->id, $updtAccount);
            }

            // update user group by this client
            $updtGroupAccount = [
                "status" => $status,
                "updt" => $now,
                "updt_by" => $req->auth->uid,
            ];
            Users::updateUsersByGroupClientId($client[0]->id, $updtGroupAccount);

            DB::commit();

            $apiResp = Responses::success("success update client");

			$log = [
				"module" => "Company",
				"action" => "Update",
				"desc" => "Update company: ".$req->cname,
			];
			UserLogs::insert(Auth::user()->id, $log);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            Storage::disk("public")->delete($url_clogo);
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_del_client(Request $req, $cid)
    {
        try {
            $now = time();

            $input = [
                "cid" => $cid,
            ];
            $rulesInput = [
                "cid" => "required|integer|not_in:0",
            ];

            // validasi input
            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $client = Clients::showClientById($cid);
            if (count($client) < 1) {
                $apiResp = Responses::not_found("client not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $user = Users::getUserByClientId($cid);

            DB::beginTransaction();

            Clients::updateClient($cid, [
                "dlt" => $now,
                "dlt_by" => $req->auth->uid,
            ]);

            // delete the client credentials only
            if (count($user) > 0) {
                // Users::updateUser($user[0]->id, [
                //     'dlt' => $now,
                //     'dlt_by' => $req->auth->uid,
                // ]);
            }

            // delete user group by this client
            Users::updateUsersByGroupClientId($client[0]->id, [
                "dlt" => $now,
                "dlt_by" => $req->auth->uid,
            ]);

            DB::commit();

            $apiResp = Responses::success("success delete client");

			$log = [
				"module" => "Company",
				"action" => "Delete",
				"desc" => "Delete company: ".$client[0]->c_name,
			];
			UserLogs::insert(Auth::user()->id, $log);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_universal_show_client_pt(Request $req)
    {
        try {
            $now = time();

            $input = [
                "cptid" => $req->cptid,
            ];
            $rulesInput = [
                "cptid" => "required|integer|not_in:0",
            ];

            // validasi input
            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $client = Clients::showClientById($req->cptid);
            if (count($client) < 1) {
                $apiResp = Responses::not_found("client not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($client[0]->user_id) {
                $client[0]->c_credentials = Clients::CCREDENTIALS_CREATE;
            } else {
                $client[0]->c_credentials = Clients::CCREDENTIALS_NOT;
            }

            $apiResp = Responses::success("success get detail client");
            $apiResp["data"] = $client[0];
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }
}
