<?php

class Member extends controller
{
    public function index($arg = '')
    {
        try {
            $qry = $this->DB->dbFetchAll("SELECT M.*, CONCAT(SUBSTRING(M.bba_address, 1, 9),'...') AS bba_address, DATE_FORMAT(registration_date, '%d-%m-%Y %H:%i') AS join_date, P.package FROM member AS M JOIN (package AS P) ON (M.package_id=P.package_id) WHERE M.status=? ORDER BY M.registration_date ASC", ['Active']);
            echo json_encode($qry);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

    private function getTotDownline($id)
    {
        $tot = 0;
        $qry = $this->DB->dbQuery("SELECT uid FROM member WHERE upline_id=?", [$id]);
        while ($downline = $this->DB->dbFetchColumn($qry)) {
            $i = $this->getTotDownline($downline);
            if ($i) $tot +=  $i;
            $tot++;
        }
        return $tot;
    }

    public function detail($id)
    {
        $qry = $this->DB->dbFetchAssoc("SELECT T.*, DATE_FORMAT(T.registration_date, '%d-%b-%Y %H:%i') AS join_date, DATE_FORMAT(TP.topup_date, '%d-%b-%Y %H:%i') AS topup_date,  P.package, (SELECT name FROM member WHERE uid=T.sponsor_id) AS sponsor_name, (SELECT name FROM member WHERE uid=T.upline_id) AS upline_name FROM member AS T JOIN (package AS P) ON (T.package_id=P.package_id) LEFT JOIN (topup AS TP) ON (T.uid=TP.uid) WHERE T.uid=?", [$id]);

        $left = $this->DB->dbFetchColumn("SELECT uid FROM member WHERE upline_id=? AND foot=?", [$id, 'Left']);
        $right = $this->DB->dbFetchColumn("SELECT uid FROM member WHERE upline_id=? AND foot=?", [$id, 'Right']);

        $totLeft = $totRight = 0;
        if ($left) {
            $totLeft = $this->getTotDownline($left);
            $totLeft++;
        }

        if ($right) {
            $totRight = $this->getTotDownline($right);
            $totRight++;
        }

        $qry['totleft'] = $totLeft;
        $qry['totright'] = $totRight;

        $qry['up'] = $qry['upline_id'] == 'TOP' ? false : true;

        echo json_encode($qry);
    }

    public function package()
    {
        $qry = $this->DB->dbFetchAll("SELECT package_id, package FROM package");
        echo json_encode($qry);
    }

    public function search($q)
    {
        $qry = $this->DB->dbFetchAll("SELECT uid, name FROM member WHERE uid LIKE ? OR name LIKE ?", ["%$q%", "%$q%"]);
        echo json_encode($qry);
    }

    /*---------------------------- CRUD --------------------*/
    private function generateUID()
    {
        $id = "";
        for ($i = 0; $i < 5; $i++)
            $id .= rand(0, 9);
        $uid = $this->DB->dbFetchObject("SELECT uid FROM member WHERE uid=?", [$id]);
        if ($uid)
            $this->generateUID();
        else return 'BBAAI-' . $id;
    }

    private function checkBBA($bba)
    {
        $bba_address = $this->DB->dbFetchColumn("SELECT COUNT(*) FROM member WHERE bba_address=?", [$bba]);
        return $bba_address ? false : true;
    }

    private function cekID($id)
    {
        $uid = $this->DB->dbFetchColumn("SELECT uid FROM member WHERE uid=?", [$id]);
        if ($uid) return ['status' => true];
        else {
            return [
                'status' => false,
                'message' => 'ID not available'
            ];
        }
    }

    private function cekFoot($id, $foot)
    {
        $tot = $this->DB->dbFetchColumn("SELECT COUNT(*) FROM member WHERE upline_id=?", [$id]);
        if ($tot < 2) {
            $uid = $this->DB->dbFetchColumn("SELECT uid FROM member WHERE upline_id=? AND foot=?", [$id, $foot]);
            if ($uid) {
                return [
                    'status' => false,
                    'message' => "Position $foot not available"
                ];
            } else
                return ['status' => true];
        } else {
            return [
                'status' => false,
                'message' => "Error Placement, max 2 branch on Upline"
            ];
        }
    }

    private function checkNode($sponsor_id, $upline_id, $foot)
    {
        if ($upline_id == 'TOP' && $sponsor_id == 'TOP') return true;
        else {
            $sponsor = $this->cekID($sponsor_id);
            $upline = $this->cekID($upline_id);
            $placement = $this->cekFoot($upline_id, $foot);

            if ($sponsor['status'] && $upline['status'] && $placement['status']) {
                return ['status' => true];
            } else {
                return !$sponsor['status'] || !$upline['status'] ? $sponsor : $placement;
            }
        }
    }


    private function generateReferralHash($str)
    {
        $code = strtolower(substr(md5($str . 'pegasusbitbossai'), 0, 16));

        $tot = $this->DB->dbFetchColumn("SELECT COUNT(*) FROM member WHERE refferal_left=? OR refferal_right=?", [$code, $code]);

        if ($tot) $this->generateReferralHash(uniqid());

        return $code;
    }

    public function register()
    {
        $account_type = $_POST['account_type'];
        $bba_address = $_POST['bba_address'];
        $name = $_POST['name'];
        $package = $_POST['package'];
        $sponsor = $_POST['sponsor'];
        $upline = $_POST['upline'];
        $position = $_POST['position'];

        $data = [];
        if ((empty($bba_address)) || (empty($package)) || (empty($sponsor)) || (empty($upline))) {
            $data = [
                'status' => 500,
                'message' => 'Field required'
            ];
        } else {
            if ($this->checkBBA($bba_address)) {
                $status = $this->checkNode($sponsor, $upline, $position);

                if ($status['status']) {
                    $id = $this->generateUID();
                    $refLeft = $this->generateReferralHash(uniqid());
                    $refRight = $this->generateReferralHash(uniqid());

                    $this->DB->dbQuery(
                        "INSERT INTO member (uid, account_type, bba_address, `name`, package_id, sponsor_id, upline_id, foot, registration_date, refferal_right, refferal_left, input_by) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",
                        [
                            $id,
                            $account_type,
                            $bba_address,
                            $name,
                            $package,
                            $sponsor,
                            $upline,
                            $position,
                            date("Y-m-d H:i:s"),
                            $refLeft,
                            $refRight,
                            $this->checkPermission()->email
                        ]
                    );
                    $data = [
                        'status' => true,
                        'message' => 'Register success'
                    ];
                } else
                    $data = $status;
            } else {
                $data = [
                    'status' => false,
                    'message' => 'BBA Address already exist'
                ];
            }
        }

        echo json_encode($data);
    }

    public function update()
    {
        $uid = $_POST['uid'];
        $name = $_POST['name'];
        $address = $_POST['bba_address'];
        $package = $_POST['package'];
        $sponsor = $_POST['sponsor'];
        $upline = $_POST['upline'];
        $position = $_POST['position'];

        /* $refLeft = $this->generateReferralHash(uniqid());
        $refRight = $this->generateReferralHash(uniqid());

        $this->DB->dbQuery("UPDATE member SET name= :name, bba_address= :address, package_id= :package, sponsor_id= :sponsor, upline_id= :upline, foot= :position, refferal_left= :reffLeft, refferal_right= :reffRight WHERE uid= :uid", ['name' => $name, 'address' => $address, 'package' => $package, 'sponsor' => $sponsor, 'upline' => $upline, 'position' => $position, 'reffLeft' => $refLeft, 'reffRight' => $refRight, 'uid' => $uid]); */

        $this->DB->dbQuery("UPDATE member SET name= :name, bba_address= :address, package_id= :package, sponsor_id= :sponsor, upline_id= :upline, foot= :position WHERE uid= :uid", ['name' => $name, 'address' => $address, 'package' => $package, 'sponsor' => $sponsor, 'upline' => $upline, 'position' => $position, 'uid' => $uid]);

        echo json_encode(['message' => 'Data has been updated']);
    }

    public function delete()
    {
        $this->DB->dbQuery("DELETE FROM member WHERE uid=?", [$_POST['id']]);
    }

    /*---------------- Max Profit -------------*/
    public function maxProfit1()
    {
        include_once "Bonus.php";


        $data = [];
        $bonus = new Bonus();

        $qry = $this->DB->dbQuery("SELECT M.*, CONCAT(SUBSTRING(M.bba_address, 1, 9),'...') AS bba_address, DATE_FORMAT(registration_date, '%d-%m-%Y %H:%i') AS join_date, P.package, P.usd FROM member AS M JOIN (package AS P) ON (M.package_id=P.package_id) WHERE M.status=? ORDER BY M.registration_date ASC", ['Active']);
        while ($obj = $this->DB->dbFetchAssoc($qry)) {


            $maxProfit = 3 * (float) $obj['usd'];

            $wd = $this->DB->dbFetchColumn("SELECT SUM(amount) FROM withdraw WHERE bba_id=?", [$obj['uid']]);
            $wd = $wd ?? 0;
            $valWd = (float) str_replace(",", "", $wd);

            $balance = $bonus->balance($obj['uid']);
            $valBalance = (float) str_replace(",", "", $balance);

            $val = round($valWd + $valBalance);
            if ($val >= $maxProfit) {
                $obj['wd'] = number_format($valWd, 2, '.', ',');
                $obj['balance'] = number_format($valBalance, 2, '.', ',');
                $obj['max_profit'] = number_format(($valWd + $valBalance), 2, '.', ',');
                $data[] = $obj;
            }
        }

        echo json_encode($data);
    }

    public function maxProfit()
    {
        include_once "Bonus.php";

        $bonus = new Bonus();

        // Ambil semua withdraw SEKALI
        $wdMap = [];
        $wdQry = $this->DB->dbQuery(
            "SELECT bba_id, SUM(amount) total 
         FROM withdraw 
         GROUP BY bba_id"
        );
        while ($w = $this->DB->dbFetchAssoc($wdQry)) {
            $wdMap[$w['bba_id']] = (float)$w['total'];
        }

        $qry = $this->DB->dbQuery("
        SELECT 
            M.*, 
            CONCAT(SUBSTRING(M.bba_address,1,9),'...') AS bba_address,
            DATE_FORMAT(M.registration_date,'%d-%m-%Y %H:%i') AS join_date,
            P.package, 
            P.usd
        FROM member M
        JOIN package P ON M.package_id=P.package_id
        WHERE M.status=?
        ORDER BY M.registration_date ASC
    ", ['Active']);

        header('Content-Type: application/json');
        echo '[';
        $first = true;

        while ($obj = $this->DB->dbFetchAssoc($qry)) {

            $maxProfit = 3 * (float)$obj['usd'];

            $valWd = $wdMap[$obj['uid']] ?? 0;
            if ($valWd) {
                $valBalance = (float)$bonus->balance($obj['uid']);

                $val = $valWd + $valBalance;

                if ($val >= $maxProfit) {
                    if (!$first) echo ',';
                    $first = false;

                    $obj['wd'] = number_format($valWd, 2, '.', ',');
                    $obj['balance'] = number_format($valBalance, 2, '.', ',');
                    $obj['max_profit'] = number_format($val, 2, '.', ',');

                    echo json_encode($obj);
                }
            }
        }
        echo ']';
    }


    /*------------------------------- Top Up ----------------------------- */
    public function listTopup()
    {
        try {
            $qry = $this->DB->dbFetchAll("SELECT M.*, CONCAT(SUBSTRING(M.bba_address, 1, 9),'...') AS bba_address, DATE_FORMAT(T.topup_date, '%d-%m-%Y %H:%i') AS topup_date, P.package FROM topup AS T JOIN (member AS M, package AS P) ON (T.uid=M.uid AND M.package_id=P.package_id) WHERE M.status=? ORDER BY M.registration_date ASC", ['Active']);
            echo json_encode($qry);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

    public function topup()
    {
        $id = $_POST['id'] ?? null;
        $topupdate = $_POST['topup_date'] ?? null;

        try {
            if ($id && $topupdate) {
                $this->DB->dbQuery("INSERT INTO topup (uid, topup_date) VALUES (?,?)", [$id, $topupdate]);
                echo json_encode(['status'=>true, 'message'=>"Topup success"]);
            }
        } catch (Exception $e) {
            http_response_code(400);
            echo json_encode(['status'=>false, 'message'=>$e->getMessage()]);
        }
    }
}
