<?php

namespace app\controller;

use app\model\EnterpriseGroup;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use think\facade\Db;

class UserGroup
{
    public function UserList($type, $group_id = '')
    {

        $data = input();

        $page = $data['page'] ?? 1;
        $pageSize = $data['pageSize'] ?? 10;
        $list = Db::table('zxc_user')->paginate([
            'list_rows' => 20,
            'query' => request()->param()
        ]);  // 获取全部数据
        
        return json($list);


    }


    public function EnterpriseGroupAdd($group_name, $group_msg)
    {
        $add = (new \app\model\EnterpriseGroup)->save(['group_name' => $group_name, 'group_msg' => $group_msg]);
        if ($add == 1) {
            $m = (new \app\model\EnterpriseGroup)->where('group_name', $group_name)->find();
            Db::table('service_fee')->save(
                ['type' => 3, 'group_id' => $m['id'], 'service_fee' => '服务费:00:00~24:00:0.40', 'station_type' => 0]
            );
            Db::table('service_fee')->save(
                ['type' => 3, 'group_id' => $m['id'], 'service_fee' => '服务费:00:00~24:00:0.40', 'station_type' => 1]
            );
            return json(['code' => 200, 'msg' => '新增成功', 'data' => $m]);
        } else {
            return json(['code' => 404, 'msg' => '新增失败']);
        }
    }

    public function EnterpriseAdd($phone, $group_id)
    {

    }

    public function NormalSearch($phone)
    {
        if (!empty($phone)) {

            $list = Db::table('zxc_user')->where('phone', $phone)->where('type', 1)->find();

            $array[] = $list;
            return json(['code' => 200, 'msg' => '请求成功', 'data' => $array]);
        } else {
            return json(['code' => 404, 'msg' => '没有数据']);
        }
        return json(['code' => 404, 'msg' => '没有数据']);

    }

    public function NormalToEnterprise($phone, $group_id)
    {

        $ll = Db::table('zxc_user')->where('phone', $phone)->find();

        $list = Db::table('zxc_user')->where('phone', $phone)->save(['type' => 3, 'group_id' => $group_id]);
        if ($list == 1) {
            $data = Db::table('zxc_user')->where('phone', $phone)->find();
            $check = EnterpriseUser::where('phone', $phone)->find();
            if (empty($check)) {
                (new \app\model\EnterpriseUser)->save(['phone' => $phone, 'group_id' => $group_id, 'openid' => $ll['openid']]);
            } else {
                (new \app\model\EnterpriseUser)->where('phone', $phone)->save(['phone' => $phone, 'group_id' => $group_id, 'openid' => $ll['openid']]);
            }
            return json(['code' => 200, 'msg' => '添加成功', 'data' => $data]);
        }
        return json(['code' => 404, 'msg' => '添加失败']);
    }

    public function GetGroup()
    {
        $group = EnterpriseGroup::select();
        return json($group);
    }

    public function DeleteEnterpriseUser($openid)
    {
        $table = 'zxc_user';
        $msg = Db::table($table)->where('openid', $openid)->find();
        if (!empty($msg)) {
            $phone = Db::table($table)->where('openid', $openid)->value('phone');
            $destroy = Db::table($table)->where('openid', $openid)->save(['type' => 1, 'group_id' => '']);
            $EnterptiseUserDelete = EnterpriseUser::where('phone', $phone)->delete();
            if ($destroy == 1 && $EnterptiseUserDelete == 1) {
                return json(['code' => 200, 'msg' => '移除成功']);
            } else {
                return json(['code' => 404, 'msg' => '移除失败']);
            }
        } else {
            return json(['code' => 404, 'msg' => '不存在该用户']);
        }
    }


    public function DeleteEnterpriseGroup($group_id)
    {
        $user = EnterpriseUser::where('group_id', $group_id)->select();
        foreach ($user as $u) {
            $this->DeleteEnterpriseUser($u['openid']);
        }
        $EnterptiseGroupDelete = EnterpriseGroup::where('id', $group_id)->delete();
        $ServerFeeDelete = ServiceFee::where('group_id', $group_id)->delete();
        if ($EnterptiseGroupDelete > 0 && $ServerFeeDelete > 0) {
            return json(['code' => 200, 'msg' => '删除成功']);
        } else {
            return json(['code' => 404, 'msg' => '删除失败']);
        }
    }

    public function PhoneSearch($phone)
    {
        $message = EnterpriseUser::where('phone', 'like', '%' . $phone . '%')->select();
        $i = 0;
        foreach ($message as $m) {
            $message[$i]['group_name'] = EnterpriseGroup::where('id', $m['group_id'])->value('group_name');
            $table = 'zxc_user';
            $account = Db::table($table)->where('openid', $m['openid'])->value('account');
            $message[$i]['account'] = $account;
            $i += 1;
        }
        return json(['data' => $message]);
    }

    public function EnterpriserUserEdit($phone, $group_id)
    {
        $o_data = EnterpriseUser::where('phone', $phone)->find();
        $o_data['group_name'] = EnterpriseGroup::where('id', $o_data['group_id'])->value('group_name');
        $edit = EnterpriseUser::where('phone', $phone)->save(['group_id' => $group_id]);
        if ($edit != 0) {
            $n_data = EnterpriseUser::where('phone', $phone)->find();
            $n_data['group_name'] = EnterpriseGroup::where('id', $n_data['group_id'])->value('group_name');
            return json(['code' => 200, 'mag' => '修改成功', 'before_data' => $o_data, 'now_data' => $n_data]);
        } else {
            return json(['code' => 404, 'msg' => '修改失败']);
        }

    }

    public function Electricity($time_type = "", $str_day = "", $charge_station_name = '')
    {

        $where = [];

        if (!empty($charge_station_name)) {
            $charge_station_ids = Db::table('charge_station')->where('charge_station_name', 'in', $charge_station_name)->column('charge_station_id');

            $ids = array_map('intval', $charge_station_ids); // 强制转为整数

            $where[] = ['charge_station_id', 'in', $ids];
        }
        // 设置日期范围
        $currentDate = $str_day ?: date('Y-m-d');
        $time_type = $time_type ?: '天';
        switch ($time_type) {
            case '天':

                $startDate = $currentDate . ' 00:00:00';
                $endDate = $currentDate . ' 23:59:59';
                break;
            case '周':
                $monday = date('Y-m-d', strtotime('monday this week', strtotime($currentDate)));
                $sunday = date('Y-m-d', strtotime('sunday this week', strtotime($currentDate)));
                $startDate = $monday . ' 00:00:00';
                $endDate = $sunday . ' 23:59:59';
                break;
            case '月':
                $firstDay = date('Y-m-01', strtotime($currentDate));
                $lastDay = date('Y-m-t', strtotime($currentDate));
                $startDate = $firstDay . ' 00:00:00';
                $endDate = $lastDay . ' 23:59:59';
                break;
            default:
                throw new Exception('不支持的统计类型');
        }


        $where[] = ['start_time', '>=', $startDate];
        $where[] = ['start_time', '<=', $endDate];
        $allData = Db::table('zxc_charge_order')
            ->where($where)
            ->field('charge_station_id, start_time, TotalPower')
            ->select();

        // 2. 初始化12个时段统计数据
        $hourlyStats = [];
        for ($hour = 0; $hour < 24; $hour += 2) {
            $startHour = str_pad($hour, 2, '0', STR_PAD_LEFT);
            $endHour = str_pad($hour + 2, 2, '0', STR_PAD_LEFT);
            $timeKey = $startHour . ':00~' . ($hour == 22 ? '23:59' : $endHour . ':00');

            $hourlyStats[$timeKey] = [
                'time_range' => $timeKey,
                'power' => '0',
                'order_count' => 0
            ];
        }

        // 3. 遍历数据按时段统计
        $totalPower = 0;
        foreach ($allData as $row) {
            $hour = date('H', strtotime($row['start_time']));
            $timeKey = $this->getTimeKeyForHour($hour);

            if (isset($hourlyStats[$timeKey])) {
                $hourlyStats[$timeKey]['power'] = bcadd($hourlyStats[$timeKey]['power'], $row['TotalPower'], 4);
                $hourlyStats[$timeKey]['order_count']++;
                $totalPower = bcadd($totalPower, $row['TotalPower'], 4);
            }
        }

        return [
            'date_range' => ['start' => $startDate, 'end' => $endDate],
            'total_power' => number_format((double)$totalPower, 4),
            'total_orders' => count($allData),
            'hourly_stats' => array_values($hourlyStats),
            'time_interval' => '2小时',
            'station' => $charge_station_name ?: '全部充电站'
        ];
    }

    /**
     * 根据小时数获取对应的时间段key
     */
    public function getTimeKeyForHour($hour)
    {
        $hour = (int)$hour;
        $start = str_pad(floor($hour / 2) * 2, 2, '0', STR_PAD_LEFT);
        $end = ($start == 22) ? '23:59' : str_pad($start + 2, 2, '0', STR_PAD_LEFT) . ':00';
        return $start . ':00~' . $end;
    }


    protected function WeedDay($startdate, $enddate)
    {

        $stimestamp = strtotime($startdate);
        $etimestamp = strtotime($enddate);
        // 计算日期段内有多少天
        $days = ($etimestamp - $stimestamp) / 86400;
        // 保存每天日期
        $date = array();
        for ($i = 0; $i < $days; $i++) {

            $date[] = date('Y-m-d 00:00:00', $stimestamp + (86400 * $i));
        }

        return $date;
    }

    public function PeriodElectricityConsumption($str_day, $charge_station_name = '')
    {
        $time = strtotime($str_day);
        $start_time = date('Y-m-d 00:00:00', $time);
        $date_start = $this->getDayDate($start_time)['start_time'];
        $date_end = $this->getDayDate($start_time)['end_time'];
        $i = 0;
        $ss = 0;
        $data = array();
        foreach ($date_start as $d) {
            $interval = substr($date_start[$ss], 11) . '~' . substr($date_end[$ss], 11);
            $data[$ss]['interval'] = $interval;
            $data[$ss]['Total'] = 0;
            $ss += 1;
        }
        foreach ($date_start as $d) {
            $table = 'zxc_charge_order';
            $d_start = date('Y-m-d H:i:s', strtotime($date_start[$i]));
            $d_end = date('Y-m-d H:i:s', strtotime($date_end[$i]));
            if (!empty($charge_station_name)) {
                $station_id = Db::table('charge_station')->where('charge_station_name', $charge_station_name)->value('charge_station_id');
                $order = Db::table($table)->where('charge_station_id', $station_id)->whereBetweenTime('start_time', $d_start, $d_end)->select();
            } else {
                $order = Db::table($table)->whereBetweenTime('start_time', $d_start, $d_end)->select();
            }
            foreach ($order as $o) {
                if (!empty($o['DetailMessage'])) {
                    if ($o['SumPeriod'] == 1) {
                        $data[$i]['Total'] += $o['TotalPower'];
                    } elseif ($o['SumPeriod'] == 2) {
                        $data[$i]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[0];
                        if ($i == 7) {
                            $data[$i - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1]; //再思考一下
                        } else {
                            $data[$i + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
                        }
                    } elseif ($o['SumPeriod'] == 3) {
                        $data[$i]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[0];
                        if ($i == 6) {
                            $data[$i + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
                            $data[$i + 1 - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[2];
                        } elseif ($i == 7) {
                            $data[$i - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
                            $data[$i - 7 + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[2];
                        }
                    }
                } else {
                    for ($a = 0; $a < count($this->GetTimeInterVal($o['start_time'], $o['end_time'])); $a++) {
                        if ($i + $a >= 7) {
                            $data[$i + $a - 7]['Total'] += round($o['TotalPower'] * $this->GetTimeInterVal($o['start_time'], $o['end_time'])[$a], 3);
                        } else {
                            $data[$i + $a]['Total'] += round($o['TotalPower'] * $this->GetTimeInterVal($o['start_time'], $o['end_time'])[$a], 3);
                        }
                    }
                }
            }
            $i += 1;
        }
        for ($k = 0; $k < count($data); $k++) {
            $data[$k]['Total'] = round($data[$k]['Total'], 2);
        }
        return $data;

    }

    public function GetTimeInterVal($start_time, $end_time)
    {
        $date = floor((strtotime($end_time) - strtotime($start_time)) / 86400);
        $minute1 = floor((strtotime($end_time) - strtotime($start_time)) % 86400 / 60) + $date * 24 * 60;
        $timeArray = $this->TimeProportion($start_time, $end_time);
        $data = array();
        for ($i = 0; $i < count($timeArray['start_time']); $i++) {
            if ($i >= 8) {
                $data['period'][$i - 8] += floor((strtotime($timeArray['end_time'][$i]) - strtotime($timeArray['start_time'][$i])) % 86400 / 60);
            } else {
                $data['period'][$i] = floor((strtotime($timeArray['end_time'][$i]) - strtotime($timeArray['start_time'][$i])) % 86400 / 60);
            }
        }
        foreach ($data['period'] as $p) {
            if ($minute1 != 0) {
                $Proportion[] = round($p / $minute1, 3);
            } else {
                $Proportion[] = 0;
            }
        }
        return $Proportion;
    }

    public function TimeProportion($order_start_time, $order_end_time)
    {
        $time = strtotime($order_start_time);
        $start_time = date('Y-m-d 00:00:00', $time);
        $end_time = date('Y-m-d 00:00:00', strtotime($order_end_time));
        $start_d = date('d', $time);
        $end_d = date('d', strtotime($order_end_time));
        $timeArray = $this->getDayDate($start_time);
        $arry2 = $this->getDayDate($end_time);
        if ($start_d != $end_d) {
            $timeArray = array_merge_recursive($timeArray, $arry2);
        }
        $data = array();
        for ($i = 0; $i < count($timeArray['start_time']); $i++) {
            if (date('Y-m-d H:i:s', strtotime($order_start_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                $data['start_time'][] = $order_start_time;
                $data['end_time'][] = $order_end_time;
            } elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                if (date('Y-m-d H:i:s', strtotime($order_start_time)) < date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                    $data['start_time'][] = $order_start_time;
                    $data['end_time'][] = date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]));
                }

            } elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                if (date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                    $data['start_time'][] = $timeArray['start_time'][$i];
                    $data['end_time'][] = $order_end_time;
                }
            } elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                if (date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
                    $data['start_time'][] = $timeArray['start_time'][$i];
                    $data['end_time'][] = $timeArray['end_time'][$i];
                }
            }
        }
        return $data;
    }

    protected function getDayDate($date)
    {
        $date_t = array();
        $date_t[] = $date;
        $this_date = strtotime($date);
        $end_date = date("Y-m-d H:i:s", strtotime('+8 hour -1 second', $this_date));
        $date_end[] = $end_date;
        $t = $this->GetPeriod($date, $end_date, $date_t, $date_end);
        $kk['start_time'] = $t[1];
        $kk['end_time'] = $t[0];
        return $kk;

    }

    protected function GetDetailMessage($message, $period)
    {
        $array = explode(';', $message, $period);
        foreach ($array as $a) {
            $arr1 = explode(',', $a);
            $degree = explode(':', $arr1[2])[1];
            $data[] = $degree;
        }
        return $data;
    }


    protected function GetPeriod($date, $end_date, $date_t, $date_end, $array1 = [8, 3, 1, 2, 3, 3, 2, 2])
    {
        for ($i = 0; $i < count($array1) - 1; $i++) {
            $this_date = strtotime($date);
            $next_date = date("Y-m-d H:i:s", strtotime('+' . $array1[$i] . ' hour', $this_date));
            $this_date_end = strtotime($end_date);
            $next_date_end = date("Y-m-d H:i:s", strtotime('+' . $array1[$i + 1] . ' hour', $this_date_end));
            $date_end[] = $next_date_end;
            $date_t[] = $next_date;
            $date = $next_date;
            $next_date_end = date("Y-m-d H:59:59", strtotime($next_date_end));
            $end_date = $next_date_end;
        }
        return [$date_end, $date_t];
    }

    public function ShowServiceFee($type, $station_type, $group_id = '')
    {
        if ($type != 3) {
            $ServiceFee = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->value('service_fee');
        } else {
            $ServiceFee = (new \app\model\ServiceFee)->where('type', $type)->where('group_id', $group_id)->where('station_type', $station_type)->value('service_fee');
        }
        if ($station_type == 0) {
            $station_type = '快充';
        } else {
            $station_type = '慢充';
        }
        $ServiceFee = str_replace('服务费:', '', $ServiceFee);
        $Server = explode(',', $ServiceFee);
        for ($index = 0; $index < count($Server); $index++) {
            $ll['time_interval'] = substr($Server[$index], 0, -5);
            $ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
            $mm[] = $ll;
        }
        return json(['code' => 200, 'Station_Type' => $station_type, 'ServiceFee' => $mm]);
    }

    public function UpdateServiceFee($type, $station_type, $fee, $group_id = '')
    {
        $service = '服务费:00:00~24:00:' . number_format((float)$fee, 2);
        if ($type == 1) {
            $update = (new \app\model\ChargeStation)->where('station_type', $station_type)->save(['ServiceFee' => $service]);
            $feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->save(['service_fee' => $service]);
            if ($update >= 1 && $feeUpdate == 1) {
                return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
            } else {
                return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
            }
        } elseif ($type == 2) {
            $feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->save(['service_fee' => $service]);
            if ($feeUpdate == 1) {
                return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
            } else {
                return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
            }
        } else {
            $feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->where('group_id', $group_id)->save(['service_fee' => $service]);
            if ($feeUpdate == 1) {
                return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
            } else {
                return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
            }
        }

    }

    public function UserVip($openid)
    {

        $type = Db::table('zxc_user')->where('openid', $openid)->value('type');
        if ($type == 1) {
            $vip = 'normal';
            return json(['code' => 200, 'vip' => $vip]);
        } elseif ($type == 2) {
            $vip = 'vip';
            return json(['code' => 200, 'vip' => $vip]);
        } elseif ($type == 3) {
            $vip = 'company';
            $group_id = EnterpriseUser::where('openid', $openid)->value('group_id');
            $group_name = EnterpriseGroup::where('id', $group_id)->value('group_name');
            return json(['code' => 200, 'vip' => $vip, 'group_name' => $group_name]);
        } else {
            return json(['code' => 1]);
        }
    }

    /**
     * @param $start_time
     * @param $end_time
     * @param string $charge_station_name
     * @param array $DataAll
     * @return \think\response\Json
     */
    protected function GetData($start_time, $end_time, string $charge_station_name, array $DataAll): \think\response\Json
    {
        $date = $this->WeedDay($start_time, $end_time);
        foreach ($date as $d) {
            $data = $this->PeriodElectricityConsumption($d, $charge_station_name);
            for ($i = 0; $i < count($data); $i++) {
                $DataAll[$i]['Total'] += $data[$i]['Total'];
            }
        }
        $all = 0;
        for ($k = 0; $k < count($DataAll); $k++) {
            $DataAll[$k]['Total'] = round($DataAll[$k]['Total'], 2);
            $all += $DataAll[$k]['Total'];
        }
        return json(['data' => $DataAll, 'all' => round($all, 2)]);
    }
}