<?php
/* 各API 需有 token_verify() token驗證function ，因各API撈取API金鑰方式不同*/
class WebAPIForMenuPage extends base_class
{

    /**
     * Leo
     * cashiser設備綁定門市
     */
    public function Create_cashier_binding($params)
    {
        //設定寫入資料
        $s_cashier_id = (string) $params["cashier"];
        $s_cashier_name = (string) $params["name"];
        $n_store_id = (int) $params["store"];
        $s_create_time = (string) $params["create_at"];
        $n_send_at = (int) $params["send_at"];
        //機台歷史紀錄型態 1:新增設備 2:設備轉移 先預設1 再進行新增或轉移判斷
        $n_cashier_history_type = 1;

        //判斷該機台是新增還是轉移
        // 機台部分
        $sql = sprintf(
            "SELECT 
                _c.cashier_id,
                _c.store_id
            FROM
                [%s].[dbo].[cashier] AS _c
            WHERE
                _c.cashier_id = :cashier_id
            ",
            $this->database_trend,
            $this->database_trend
        );
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute([
            "cashier_id" => $s_cashier_id,
        ]);
        $row = $sth->fetch(PDO::FETCH_ASSOC);
        // 若cashier編號已存在表中 則為設備轉移
        // (API驗證時已阻擋掉cashier編號已綁定指定門市的問題，因此只要這邊條件下有資料，那必為設備轉移)
        if (!empty($row)) {
            $n_cashier_history_type = 2;
        }
        // 判斷該門市為新建立門市或是舊有門市進行設備更換
        // 門市部分 (順便取得零用金設定並初始化零用金
        $sql = sprintf(
            "SELECT 
                _c.cashier_id,
                _s.store_id,
                _s.petty_cash_500,
                _s.petty_cash_100,
                _s.petty_cash_50,
                _s.petty_cash_10,
                _s.petty_cash_5,
                _s.petty_cash_1
            FROM
                [%s].[dbo].[store] AS _s
                LEFt JOIN [%s].[dbo].[cashier] AS _c ON _c.store_id = _s.store_id
            WHERE
                _s.store_id = :store_id
            ",
            $this->database_trend,
            $this->database_trend
        );
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute([
            "store_id" => $n_store_id,
        ]);
        $row = $sth->fetch(PDO::FETCH_ASSOC);
        // 設定舊cashier編號
        $s_old_cashier_id = "";
        if (!empty($row["cashier_id"])) {
            $s_old_cashier_id = $row["cashier_id"];
        }
        //設定各面額補入的零用金
        $n_petty_cash_500 = $row["petty_cash_500"];
        $n_petty_cash_100 = $row["petty_cash_100"];
        $n_petty_cash_50 = $row["petty_cash_50"];
        $n_petty_cash_10 = $row["petty_cash_10"];
        $n_petty_cash_5 = $row["petty_cash_5"];
        $n_petty_cash_1 = $row["petty_cash_1"];

        if (
            $n_petty_cash_500 == 0 &&
            $n_petty_cash_100 == 0 &&
            $n_petty_cash_50 == 0 &&
            $n_petty_cash_10 == 0 &&
            $n_petty_cash_5 == 0 &&
            $n_petty_cash_1 == 0
        ) {
            throw new Exception("該門市尚未設定零用金", 92000);
        }
        //開始 beginTransaction
        $this->pdo_sql->beginTransaction();

        //舊機台異動部分 若該門市原先已有綁定舊cashier編號，需先將舊有機台store_id改為0
        if ($s_old_cashier_id != "") {
            $sql = sprintf(
                "UPDATE
                    [%s].[dbo].[cashier] 
                SET
                    [update_at] = :update_at,
                    [store_id] = 0
                WHERE
                    [cashier_id] = :cashier_id",
                $this->database_trend
            );
            $sql_val = [
                "cashier_id" => $s_old_cashier_id,
                "update_at" => $s_create_time
            ];
            //準備執行sql
            $sth = $this->pdo_sql->prepare($sql);
            $sth->execute($sql_val);
            if ($sth->rowCount() == 0) {
                //錯誤異常時回滾
                $this->pdo_sql->rollBack();
                throw new Exception("門市舊機台異動寫入失敗", 92000);
            }
        }

        //新機台異動部分
        //新增機台
        if ($n_cashier_history_type == 1) {
            $sql = sprintf(
                "INSERT INTO 
                    [%s].[dbo].[cashier] 
                ( 
                    [cashier_id], 
                    [cashier_name], 
                    [store_id], 
                    [create_at],
                    [update_at] 
                )
                VALUES
                    ( 
                        :cashier_id, 
                        :cashier_name, 
                        :store_id,
                        :create_at,
                        :update_at
                    );",
                $this->database_trend
            );
            $sql_val = [
                "cashier_id" => $s_cashier_id,
                "cashier_name" => $s_cashier_name,
                "store_id" => $n_store_id,
                "create_at" => $s_create_time,
                "update_at" => $s_create_time,
            ];
        }
        //機台轉移
        else {
            //當前機台進行門市綁定
            $sql = sprintf(
                "UPDATE
                    [%s].[dbo].[cashier] 
                SET
                    [cashier_name] = :cashier_name,
                    [store_id] = :store_id,
                    [update_at] = :update_at
                WHERE
                    [cashier_id] = :cashier_id",
                $this->database_trend
            );
            $sql_val = [
                "cashier_id" => $s_cashier_id,
                "cashier_name" => $s_cashier_name,
                "store_id" => $n_store_id,
                "update_at" => $s_create_time
            ];
        }
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute($sql_val);
        if ($sth->rowCount() == 0) {
            //錯誤異常時回滾
            $this->pdo_sql->rollBack();
            throw new Exception("機台綁定寫入失敗", 92000);
        }

        //初始化零用金補入 type 為 2 純補入
        /*$a_insert_arr = [
            "cashier_id" => $s_cashier_id,
            "store_id" => $n_store_id,
            "create_at" => $s_create_time,
            "cycle_box_50" => $n_petty_cash_50,
            "cycle_box_10" => $n_petty_cash_10,
            "cycle_box_5" => $n_petty_cash_5,
            "cycle_box_1" => $n_petty_cash_1,
            "sub_500_out" => $n_petty_cash_500,
            "sub_100_out" => $n_petty_cash_100,
            "operate_type" => 2,
        ];
        //拼接sql字串
         $sql = sprintf(
            "INSERT INTO [%s].[dbo].[cashier_currency_statement](
                cashier_id,
                store_id,
                create_at,
                cycle_box_50,
                cycle_box_10,
                cycle_box_5,
                cycle_box_1,
                sub_500_out,
                sub_100_out,
                operate_type
            )
            VALUES
            (
                :cashier_id,
                :store_id,
                :create_at,
                :cycle_box_50,
                :cycle_box_10,
                :cycle_box_5,
                :cycle_box_1,
                :sub_500_out,
                :sub_100_out,
                :operate_type
            )
			",
            $this->database_trend
        );
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute($a_insert_arr);
        if ($sth->rowCount() == 0) {
            //錯誤異常時回滾
            $this->pdo_sql->rollBack();
            throw new Exception("零用金寫入失敗", 92000);
        }*/
        //新增機台歷史紀錄
        $sql = sprintf(
            "INSERT INTO 
                [%s].[dbo].[cashier_history] 
            ( 
                [cashier_id], 
                [store_id], 
                [type], 
                [create_at]
                )
            VALUES
                ( 
                    :cashier_id, 
                    :store_id,
                    :type,
                    :create_at
                );",
            $this->database_trend
        );
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute([
            "cashier_id" => $s_cashier_id,
            "store_id" => $n_store_id,
            "create_at" => $s_create_time,
            "type" => $n_cashier_history_type,
        ]);
        if ($sth->rowCount() == 0) {
            //錯誤異常時回滾
            $this->pdo_sql->rollBack();
            throw new Exception("機台歷史資料寫入失敗", 92000);
        }

        //結束 Transaction 執行寫入
        $this->pdo_sql->commit();

        //門市綁定完成後才可更新最後連線時間
        $this->cashier_connect_time_update($n_store_id, $s_cashier_id, $n_send_at);

        return "OK";
    }
    /**
     * Leo
     * api 驗證
     */
    public function api_verify($token, $params)
    {
        //門市編號
        $n_store_id = (int) $params["store"];
        if ($n_store_id == 0) { //門市編號為空
            throw new Exception("store 欄位不可為空", 91000);
        } else {    //檢查門市是否存在，以及該門市是否已經綁定機台
            $sql = sprintf(
                "SELECT 
                        _s.store_id
                        ,_c.cashier_id
                FROM 	
                    [%s].[dbo].[store] AS _s 
                    LEFT JOIN [%s].[dbo].[cashier] AS _c ON _c.store_id = _s.store_id
                WHERE
                    _s.store_id = :store_id ",
                $this->database_trend,
                $this->database_trend
            );
            //準備執行sql
            $sth = $this->pdo_sql->prepare($sql);
            $sth->execute([
                "store_id" => $n_store_id
            ]);
            $row = $sth->fetch(PDO::FETCH_ASSOC);
            if (empty($row)) { //查無門市
                throw new Exception("store 異常", 91000);
            } else if (!empty($row["cashier_id"])) {
                //預計綁定的門市已與要綁定的機台綁定，不須重新設定
                if ($row["cashier_id"] == trim($params["cashier"])) {
                    throw new Exception("the store and cashier has been banding ", 91000);
                }
            }
        }
        //機台序號
        $s_cashier_id = (string) $params["cashier"];
        if ($s_cashier_id == "") { //機台編號為空
            throw new Exception("cashier 欄位不可為空", 91000);
        }
        //機台名稱
        $s_cashier_name = (string) $params["name"];
        if (trim($s_cashier_name) == "") { //機台名稱為空
            throw new Exception("name 欄位不可為空", 91000);
        }
        //時間戳(單位秒)
        $s_send_at = (string) $params["send_at"];
        if ($s_send_at == "") { //時間戳為空
            throw new Exception("send_at 欄位不可為空", 91000);
        } else if ($this->check_timestamp_format($s_send_at) != true) {
            throw new Exception("send_at format error", 91000);
        }
        //Token
        if (trim($token) == "") { //Token為空
            throw new Exception("token 欄位不可為空", 91000);
        }

        //依據資料查詢門市API金鑰來進行Token驗證
        $sql = sprintf(
            "SELECT 
                    _s.store_api_key
            FROM 	
                 [%s].[dbo].[store] AS _s 
            WHERE
                _s.store_id = :store_id ",
            $this->database_trend
        );
        //準備執行sql
        $sth = $this->pdo_sql->prepare($sql);
        $sth->execute([
            "store_id" => $n_store_id
        ]);
        $row = $sth->fetch(PDO::FETCH_ASSOC);
        if (!empty($row)) {
            $s_api_key = $row["store_api_key"];
            if ($this->shopee_api_token_verify($token, $s_api_key, $s_send_at) != true) {
                throw new Exception("Token Verification Failed", 91001);
            }
        }
    }
}
