<?php

namespace App\Http\Controllers\Admin;

use App\Exports\OrderMedicalReportExport;
use App\Exports\OrderStepThreeInfoExport;
use App\Exports\OrderUserInfoExport;
use App\Exports\UserExport;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserInfoResource;
use App\Http\Response\ResponseJson;
use App\Models\ApplyScanQrcode;
use App\Models\DmaProcessLog;
use App\Models\FatLog;
use App\Models\HealthLog;
use App\Models\InviteUser;
use App\Models\MedicalReport;
use App\Models\Order;
use App\Models\OtherHealthFile;
use App\Models\Partner;
use App\Models\RecommendUser;
use App\Models\S2ApiLog;
use App\Models\ScanQrcodeUser;
use App\Models\ServiceRole;
use App\Models\ServiceUser;
use App\Models\User;
use App\Models\UserInfo;
use App\Models\Version;
use App\Services\ChatService;
use Illuminate\Http\Request;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Maatwebsite\Excel\Facades\Excel;

class UserController extends Controller
{
    use ResponseJson;

    public function users(Request $request)
    {
        $users = User::with('recommendUser:user_id,name', 'shareUser');
        $keyword = $request->input('keyword');
        if ($keyword) {
            $keyword = trim($keyword);
            $users = $users->where(function ($sql) use ($keyword) {
                $sql->where('name', 'like', '%' . $keyword . '%')
                    ->orWhere("id", "like", "%$keyword%")
                    ->orWhere('mobile', 'like', '%' . $keyword . '%')
                    ->orWhere('mobile', aesEncryptCBC($keyword));
            });
        }

        $platform = $request->input("platform");
        $users = $users->when($platform, function ($query) use ($platform) {
            $query->where('platform', "like", "%$platform%");
        });
        $source = $request->input("source");
        if (!empty($source)) {
            $source = json_decode($source, true);
        } else {
            $source = [1, 4];
        }

        // $source = $request->input("source");
        $users = $users->when($source, function ($query) use ($source) {
            $query->whereIn('source', $source);
        });

        // $type = $request->input('type');
        // if ($type) {
        //     if ($type == "H5") {
        //         $users = $users->whereHas("officialWechat");
        //     } elseif ($type == 'MP') {
        //         $source = [1, 4];
        //         $users = $users->where(function ($sql) use ($source) {
        //             $sql->whereIn('source', $source);
        //         });
        //     } elseif ($type == 'WORK') {
        //         $source = [3];
        //         $users = $users->where(function ($sql) use ($source) {
        //             $sql->whereIn('source', $source);
        //         });
        //     }
        // }


        $nopage = $request->input("nopage");
        if ($nopage) {
            $users = $users->orderByDesc('id')->limit(50)
                ->get();
        } else {
            $users = $users->orderByDesc('id')
                ->paginate();
        }

        foreach ($users as $user) {
            $user->makeVisible('mobile');
        }
        return $this->success('ok', $users);
    }

    public function updateRecommendUser(Request $request, User $user)
    {
        $recommend_user_id = $request->input('recommend_user_id');
        RecommendUser::updateOrCreate(['user_id' => $user->id], ['recommend_user_id' => $recommend_user_id]);
        return $this->success('ok');
    }


    /**
     * 导出小程序人员
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function userExport(Request $request)
    {
        return Excel::download(new UserExport($request->all()), '用户.xlsx');
    }

    /**
     * 查看用户详情
     * @param Request $request
     * @param User $user
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function user(Request $request, User $user)
    {
        $type = $request->get('type');
        $is_export = $request->get('is_export');
        $user_info = UserInfo::where('user_id', $user->id)->first();
        if (empty($user_info)) {
            $user_info = UserInfo::create(['user_id' => $user->id]);
        }
        $user_info = UserInfoResource::make($user_info);
        foreach (User::STEP_CONFIG_KEY as $index) {
            if (!isset($user_info->$index)) {
                continue;
            }
            $arr = json_decode($user_info->$index, true);
            if (!is_array($arr)) {
                continue;
            }
            foreach ($arr as $key => $value) {
                if ($value['state'] == 0) {
                    unset($arr[$key]);
                    continue;
                }
                $arr[$key]['name'] = trans('app.' . $index . '.' . $value['key']);
            }
            $user_info->$index = json_encode(array_values($arr));
        }
        if ($is_export) {
            $data['user'] = $user;
            $data['user_info'] = $user_info;
            if ($type == 1) {
                return Excel::download(new OrderUserInfoExport($data), '基本信息.xlsx');
            } elseif ($type == 2) {
                return Excel::download(new OrderStepThreeInfoExport($data), '问卷调查.xlsx');
            } elseif ($type == 3) {
                return Excel::download(new OrderMedicalReportExport($data), '体检报告.xlsx');
            }
        }

        $user->bp_amount = $user->bp ? $user->bp->bp : 0;

        $key = "user:" . $user->id . ":device_info";
        // 服务对象设备信息
        $device_info = Redis::get($key);
        Log::info($key);
        Log::info($device_info);
        if (empty($device_info)) {
            $device_info = ["version" => [], "phone_model" => [], "system_version" => [], "source" => []];
            $log = S2ApiLog::where("user_id", $user->id)->orderBy("id", "desc")->first();
            if ($log && $log->header) {
                $headers = json_decode($log->header, true);
                $device_info['version'] = $headers["Version"] ?? [];
                $device_info['phone_model'] = $headers["Phone-Model"] ?? [];
                $device_info['system_version'] = $headers["System-Version"] ?? [];
                $device_info['source'] = $headers["Source"] ?? [];
            }
            $device_info_str = json_encode($device_info);
            Redis::setex($key, 1 * 60 * 60, $device_info_str);
        } else {
            $device_info = json_decode($device_info, true);
        }
        $user->version = count($device_info["version"]) ? $device_info["version"][0] : "";
        $user->platform = count($device_info["source"]) ? $device_info["source"][0] : "";
        $user->system_version = count($device_info['system_version']) ? $device_info["system_version"][0] : "";

        return $this->success('ok', compact('user', 'user_info'));
    }

    /**
     * 获取测量数据
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getUserFatLog(Request $request)
    {
        try {
            $user_id = $request->get('user_id');
            $page_size = $request->get('page_size', 15);
            $fat_log = FatLog::where('user_id', $user_id)
                ->select()
                ->orderByDesc('id')
                ->paginate($page_size);
            return $this->success('ok', $fat_log);
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    public function medicalReports(Request $request, User $user)
    {
        $type = $request->get('type');
        $reports = $user->medicalReports()->where('type', $type)->orderByDesc('id')->get();
        foreach ($reports as $report) {
            $content = json_decode($report->content, true);
            $report->content = $content;
            $report->body_images = json_decode($report->body_images);
        }
        //        $is_export = $request->get('is_export');
//        if($is_export){
//            return Excel::download(new OrderMedicalReportExport($reports), '体检报告.xlsx');
//        }
        return $this->success('ok', $reports);
    }

    public function AddMedicalReports(Request $request, User $user)
    {
        $medical_report = $request->input('medical_report');
        $medical_report_file = $request->input('medical_report_file');
        $medical_date = $request->input('medical_date');
        $anomaly = $request->input('anomaly', []);
        $anomaly = json_encode($anomaly);
        $desc = $request->input("desc", "");
        //检测类型
        $anomaly_type = $request->input('anomaly_type', 1);

        $type = $request->input('type', MedicalReport::TYPE_BEFORE);
        if (is_array($medical_report)) {
            $medical_report = json_encode($medical_report);
        }
        if (is_array($medical_report_file)) {
            $medical_report_file = json_encode($medical_report_file);
        }

        MedicalReport::create(['user_id' => $user->id, 'type' => $type, 'content' => $medical_report, "content_file" => $medical_report_file, 'medical_date' => $medical_date, 'desc' => $desc, 'anomaly' => $anomaly, 'anomaly_type' => $anomaly_type]);

        $order = Order::getPayOrder($user->id);
        $chatService = new ChatService();
        if ($type == MedicalReport::TYPE_BEFORE) {
            DmaProcessLog::addUserProcessLog($order->user_id ?? 0, $order->id ?? 0, 1, "send_check_health", "系统发送健康档案待确认通知", auth()->id(), 0);
        }

        if ($type == MedicalReport::TYPE_AFTER) {
            DmaProcessLog::addUserProcessLog($order->user_id ?? 0, $order->id ?? 0, 1, "upload_after_report", "后台上传复检报告", $order->user_id ?? 0, 0);
            DmaProcessLog::addUserProcessLog($order->user_id ?? 0, $order->id ?? 0, 1, "send_upload_after_report_msg", "系统发送复检报告上传通知", auth()->id(), 0);
            if (config("app.env") == "production") {
                $chatService->sendImMsgUserToUser($order->id ?? 0, '系统通知', ($order->name ?? "") . '后台已上传复检报告', 'https://image.fulllinkai.com/202403/29/dea3e0c27107cdf178635d2a41199e5e.png', 'yfheal://app/push/MedicalExaminReport', [ServiceRole::MAIN_COACH]);
            }
        }
        return $this->success('ok');
    }

    public function otherHealth(Request $request, User $user)
    {
        $type = $request->get('type');
        $reports = $user->otherHealthFile()->where('type', $type)->orderByDesc('id')->get();
        foreach ($reports as $report) {
            $report->images = json_decode($report->images);
        }
        return $this->success("ok", $reports);
    }

    /**
     *
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getInviteUserList(Request $request)
    {
        try {
            $keyword = $request->get('keyword');
            $user_id = $request->get('user_id');
            $page_size = $request->get('page_size', 15);
            $list = InviteUser::when($keyword, function ($query) use ($keyword) {
                $query->where(function ($query) use ($keyword) {
                    $query->where('invite_user.name', 'like', "%{$keyword}%")
                        ->orWhere('invite_user.mobile', 'like', "%{$keyword}%")
                        ->orWhere('users.name', 'like', "%{$keyword}%");
                });
            })->when($user_id !== null, function ($query) use ($user_id) {
                $query->where('user_id', $user_id)
                    ->orWhere('invite_user_id', $user_id);
            })->join('users', 'users.id', '=', 'invite_user.user_id')
                ->select('invite_user.*', 'users.name as wx_name', 'users.avatar')
                ->orderByDesc('id')
                ->paginate($page_size);
            foreach ($list as $k => $v) {
                $invite_user = Partner::where('user_id', $v->invite_user_id)->first();
                $v->invite_user_name = $invite_user->name ?? '';
            }
            return $this->success('ok', $list);
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    /**
     * 电视展示页获取扫码统计数据
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getWebCountScanUser()
    {
        try {
            // 获取今天零点的时间戳
            $today_start = strtotime('today');
            // 获取明天零点的时间戳
            $tomorrow_start = $today_start + 86400;
            // 格式化时间戳为日期时间字符串
            $start_time = date('Y-m-d H:i:s', $today_start);
            $end_time = date('Y-m-d H:i:s', $tomorrow_start);
            $scan_count = ScanQrcodeUser::whereBetween('created_at', [$start_time, $end_time])->count();
            $invite_count = InviteUser::whereBetween('created_at', [$start_time, $end_time])->count();
            return $this->success('ok', compact('scan_count', 'invite_count'));
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }


    public function getNowDateTime()
    {
        $data = [];
        date_default_timezone_set('Asia/Shanghai');
        $endDate = new \DateTime(); // 当前日期
        // $timestamp = time();
        // $endDate->timestamp = $timestamp;
        $dateTime = $endDate->format('Y-m-d H:i:s');

        $data["timestamp"] = strtotime($dateTime);
        $data["end_date"] = $endDate;
        $data["dateTime"] = $dateTime;

        Log::info("getNowDateTime 获取当前时间");
        Log::info(json_encode($data));
        return $this->success("ok", $data);
    }

    /**
     * 获取电视展示页近6天数据
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function getWebScanData()
    {
        try {
            $dates = array();
            date_default_timezone_set('Asia/Shanghai');
            $endDate = new \DateTime(); // 当前日期
            Log::info("getWebScanData 获取当前时间");
            Log::info(json_encode($endDate));
            $endDate->sub(new \DateInterval('P1D'));

            for ($i = 0; $i < 7; $i++) {
                $dates[] = $endDate->format('Y-m-d');
                $endDate->sub(new \DateInterval('P1D')); // 减去一天
            }
            $dates = array_reverse($dates); // 翻转数组，使日期按照从过去到现在的顺序排列
            $result = [];
            foreach ($dates as $k => $val) {
                // $dayOfWeek = date('N', strtotime($val));
                // if ($dayOfWeek == 7) {
                //     continue;
                // }
                $date = date('m-d', strtotime($val));
                $count = ScanQrcodeUser::where('created_at', 'like', $val . '%')->count();
                $result[$k]['name'] = $date;
                $result[$k]['value'] = $count;
            }
            $result = array_values($result);
            return $this->success('ok', $result);
        } catch (\Exception $e) {
            Log::info('getWebScanData:' . $e->getMessage());
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    /**
     * 获取签到统计数
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getAdminCountSanUser(Request $request)
    {
        try {
            $date = $request->get('date');
            [$start_time, $end_time] = get_day_time($date);
            $count = ScanQrcodeUser::select(
                DB::raw('count(if(type = 1,1,null)) as service_user_count'),
                DB::raw('count(if(type = 2,1,null)) as custom_user_count'),
                DB::raw('count(if(type = 3,1,null)) as other_user_count')
            )->whereBetween('created_at', [$start_time, $end_time])
                ->get();
            return $this->success('ok', $count[0]);
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    /**
     * 获取扫码签到人员列表
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getScanUserList(Request $request)
    {
        try {
            $keyword = $request->get('keyword');
            $type = $request->get('type');
            $date = $request->get('date');
            [$start_time, $end_time] = get_day_time($date);
            $page_size = $request->get('page_size', 15);
            $list = ScanQrcodeUser::when($keyword, function ($query) use ($keyword) {
                $query->where(function ($query) use ($keyword) {
                    $query->where('name', 'like', "%{$keyword}%")
                        ->orWhere('mobile', 'like', "%{$keyword}%");
                });
            })->when($type !== null, function ($query) use ($type) {
                $query->where('type', $type);
            })->when($date !== null, function ($query) use ($start_time, $end_time) {
                $query->whereBetween('created_at', [$start_time, $end_time]);
            })
                ->orderByDesc('id')
                ->paginate($page_size);

            foreach ($list as $item) {
                $date_time = date('Y-m-d', strtotime($item->created_at));
                $item->apply_user_name = '';
                $item->apply_user_mobile = '';
                $item->apply_user_avatar = '';
                $apply = ApplyScanQrcode::where('date', $date_time)->where('user_id', $item->user_id)->first();
                if (!$apply) {
                    continue;
                }
                $apply_user = Partner::where('user_id', $apply->invite_user_id)->first();
                if (!$apply) {
                    continue;
                }
                $item->apply_user_name = $apply_user->name;
                $item->apply_user_mobile = $apply_user->mobile;
                $item->apply_user_avatar = $apply_user->pic;
            }
            return $this->success('ok', $list);
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    /**
     * 帮用户申请扫码签到列表
     * @param Request $request
     */
    public function applyUserScanQrcode(Request $request)
    {
        try {
            $keyword = $request->get('keyword');
            $date = $request->get('date');
            $page_size = $request->get('page_size', 15);
            $list = ApplyScanQrcode::when($keyword, function ($query) use ($keyword) {
                $query->where(function ($query) use ($keyword) {
                    $query->where('partners.name', 'like', "%{$keyword}%")
                        ->orWhere('partners.mobile', 'like', "%{$keyword}%");
                });
            })->when($date !== null, function ($query) use ($date) {
                $query->where('date', $date);
            })->join('partners', 'partners.user_id', '=', 'apply_scan_qrcode.invite_user_id')
                ->select('apply_scan_qrcode.*', 'partners.name', 'partners.mobile', 'partners.pic')
                ->orderByDesc('date')
                ->paginate($page_size);

            foreach ($list as $item) {
                $user_info = InviteUser::where('invite_user_id', $item->invite_user_id)->where('user_id', $item->user_id)->first();
                $user = User::where('id', $item->user_id)->first();
                $item->user_name = $user_info->name ?? '';
                $item->user_mobile = $user_info->mobile ?? '';
                $item->user_avatar = $user->avatar ?? '';
                $item->user_wx_name = $user->name ?? '';

                $item->status = 0;
                $exists = ScanQrcodeUser::where('user_id', $item->user_id)
                    ->where('created_at', 'like', $item->date . '%')
                    ->exists();
                if ($exists) {
                    $item->status = 1;
                }
                if ($item < $date && !$exists) {
                    $item->status = 2;
                }
            }
            return $this->success('ok', $list);
        } catch (\Exception $e) {
            Log::error('applyUserScanQrcode:' . $e->getMessage());
            return $this->failure('查询失败');
        }
    }

    /**
     * 添加h5版本号
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function addVersion(Request $request)
    {
        try {
            $version = $request->input('version');
            if (empty($version))
                return $this->failure('版本号不为空');

            $type = $request->input('type');

            $version_info = Version::where('version', $version)->where('type', $type)->first();

            if ($version_info) {
                return $this->failure('版本号已存在');
            }

            $status = $request->input('status');

            $remark = $request->input('remark');

            $map = [];
            $map['version'] = $version;
            $map['remark'] = $remark;
            $map['type'] = $type;
            $map['status'] = $status;

            Version::create($map);
            return $this->success('ok');
        } catch (\Exception $e) {
            Log::error('addVersion:' . $e->getMessage());
            return $this->failure('添加失败');
        }
    }

    /**
     * 获取版本号列表
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getVersionList(Request $request)
    {
        try {
            $keyword = $request->get('keyword');
            $type = $request->get('type');
            $list = Version::when($keyword, function ($query) use ($keyword) {
                $query->where(function ($query) use ($keyword) {
                    $query->where('version', 'like', "%{$keyword}%");
                });
            })->when($type !== null, function ($query) use ($type) {
                $query->where('type', $type);
            })
                ->orderByDesc('id')
                ->paginate();
            return $this->success('ok', $list);
        } catch (\Exception $e) {
            Log::error('getVersionList:' . $e->getMessage());
            return $this->failure('获取失败');
        }
    }

    /**
     * 编辑版本号
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function editVersion(Request $request)
    {
        try {
            $id = $request->get('id');
            if (empty($id)) {
                return $this->failure('id不为空');
            }
            $version_info = Version::where('id', $id)->first();

            $version = $request->get('version');
            if (!empty($version)) {
                $version_info->version = $version;
            }
            $remark = $request->get('remark');
            if (!empty($remark)) {
                $version_info->remark = $remark;
            }

            $type = $request->get('type');
            if (isset($type)) {
                $version_info->type = $type;
            }

            $status = $request->get('status');
            if (isset($status)) {
                $version_info->status = $status;
            }
            $version_info->save();
            return $this->success('ok');
        } catch (\Exception $e) {
            return $this->failure('编辑失败');
        }
    }
}
