<?php

namespace App\Http\Controllers\Admin;

use App\Events\OperationLoggedEvent;
use App\Exports\AgencyExport;
use App\Exports\AgencyUserExport;
use App\Exports\CompanyPartnersExport;
use App\Exports\PartnersExport;
use App\Http\Controllers\Controller;
use App\Http\Response\ResponseJson;
use App\Models\Agency;
use App\Models\AgencyUser;
use App\Models\Coach;
use App\Models\Partner;
use App\Models\PartnerCommission;
use App\Models\PartnerWithdrawal;
use App\Models\Province;
use App\Models\Quota;
use App\Models\ServiceUser;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rules\In;
use Maatwebsite\Excel\Facades\Excel;

use function PHPUnit\Framework\isNull;

class PartnerController extends Controller
{
    use ResponseJson;

    public function partners(Request $request)
    {
        $keyword = $request->input('keyword');
        $status = $request->input('status', null);
        $partners = Partner::query()
            ->whereHas('user')
            ->when($status != null, function ($query) use ($status) {
                $query->where('status', $status);
            });

        if ($keyword) {
            $partners = $partners->where(function ($sql) use ($keyword) {
                $sql->where("name", 'like', '%' . $keyword . '%')
                    ->orWhere('mobile', 'like', '%' . $keyword . '%');
            });
        }
        $nopage = $request->input('nopage');
        if ($nopage) {
            $partners = $partners->orderByDesc('updated_at')->orderByDesc('id')->limit(15)->get();
        } else {
            $partners = $partners->orderByDesc('updated_at')->orderByDesc('id')->paginate();
        }
        return $this->success('ok', $partners);
    }

    public function partnersExport()
    {
        return Excel::download(new PartnersExport(), '合作伙伴.xlsx');
    }


    public function companyPartners(Request $request)
    {
        $page_size = $request->get('page_size', 15);

        $users = ServiceUser::with('roles', 'user:id,name,avatar')
            ->whereNotNull('user_id')
            ->when($request->filled('keyword'), function ($query) use ($request) {
                $keyword = trim($request->input('keyword'));
                $query->where(function ($query) use ($keyword) {
                    $query->where('name', 'like', "%{$keyword}%")
                        ->orWhere('mobile', 'like', "%{$keyword}%");
                });
            })
            ->whereHas('roles', function ($query) {
                $query->where('service_roles.id', 5);
            })
            ->orderByDesc('id')
            ->paginate(perPage: $page_size);

        $users->each(function ($user) {

            $user->protocol = json_decode($user->protocol) ?: [];
        });
        return $this->success('ok', $users);
    }

    public function companyPartnersExport()
    {
        return Excel::download(new CompanyPartnersExport(), '渠道商.xlsx');
    }

    public function partner(Request $request, Partner $partner)
    {
        //代理
        $agencies = $partner->agencies;
        $service_role = $partner->service_roles;
        return $this->success('ok', $partner);
    }

    public function updatePartner(Request $request, Partner $partner)
    {
        $name = $request->input("name");
        if ($name && $name != $partner->name) {
            $partner->name = $name;
        }

        $mobile = $request->input("mobile");
        if ($mobile && $mobile != $partner->mobile) {
            $exist = Partner::where('mobile', $mobile)->where('id', '<>', $partner->id)->exists();
            if ($exist)
                return $this->failure("手机号存在账号");
            $partner->mobile = $mobile;
        }

        $pic = $request->input("pic");
        if ($pic && $name != $partner->pic) {
            $partner->pic = $pic;
        }

        $intro = $request->input("intro");
        if ($intro && $name != $partner->intro) {
            $partner->intro = $intro;
        }

        $specialty = $request->input("specialty");
        if ($specialty && $specialty != json_encode($partner->specialty)) {
            $partner->specialty = json_encode($specialty);
        }

        $protocols = $request->input("protocols");
        if ($protocols && $protocols != json_encode($partner->protocols)) {
            $partner->protocols = json_encode($protocols);
        }

        $partner->save();

        //操作记录
        OperationLoggedEvent::dispatch("修改了合作伙伴: $partner->id 的信息");
        return $this->success('ok');
    }

    public function deletePartner(Request $request, Partner $partner)
    {
        $id = $partner->id;
        $partner->delete();
        //操作记录
        OperationLoggedEvent::dispatch("删除了合作伙伴: $id");
        return $this->success('ok');
    }

    public function agencies(Request $request, Agency $agency)
    {
        $keyword = $request->input('keyword');
        $grade = $request->input('grade');
        $nopage = request()->input('nopage', 0);
        $is_export = $request->input('is_export');
        if ($is_export) {
            $nopage = true;
        }
        $query = $agency->query()->with('agencyUser.collaborator');
        $query->when($grade, function ($query) use ($grade) {
            $query->where('grade', $grade);
        });
        if ($keyword) {
            $query->where(function ($sql) use ($keyword) {
                $sql->where("province", 'like', '%' . $keyword . '%')
                    ->orWhere('city', 'like', '%' . $keyword . '%');
            });
        }

        $query->orderByDesc('id');

        if ($nopage) {
            $list = $query->get();
        } else {
            $list = $query->paginate();
        }
        if ($is_export) {
            return Excel::download(new AgencyExport($list), '分公司.xlsx');
        }
        return $this->success('ok', $list);
    }

    /**
     * 获取分公司列表
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getAgentList(Request $request)
    {
        $agency = Agency::query()->with('quota.collaboratorInfo')
            ->orderByDesc('id')->get();
        return $this->success('ok', $agency);
    }

    public function storeAgency(Request $request)
    {
        $agencies = $request->input('agencies');
        foreach ($agencies as &$agency) {
            if ($agency['grade'] == "C") {
                $name = $agency['city'];
                $exists = Agency::where('city', 'like', '%' . $agency['city'] . '%')->exists();
            } else {
                $name = $agency['province'];
                $exists = Agency::where('province', 'like', '%' . $agency['province'] . '%')->exists();
            }
            if ($exists) {
                return $this->failure($name . '分公司已存在');
            }
            $agency['created_at'] = $agency['updated_at'] = date("Y-m-d H:i:s");
        }
        Agency::insert($agencies);

        return $this->success('ok');
    }

    public function getAgencyDetail($id)
    {
        $detail = Agency::find($id);
        return $this->success('ok', $detail);
    }

    public function updateAgency(Request $request, $id, Agency $agency)
    {
        $data = $request->only(['grade', 'pro_id', 'city_id', 'province', 'city']);
        //        $detail = $agency->find($id);
        $agency->where('id', $id)->update($data);
        return $this->success('ok');
    }

    public function deleteAgency(Agency $agency, $id)
    {
        $agency->where('id', $id)->delete();
        return $this->success('ok');
    }

    public function addAgencyUser(Request $request)
    {
        $collaborator_id = $request->input('collaborator_id');
        $agency_id = $request->input('agency_id');
        $is_leader = $request->input('is_leader');
        AgencyUser::create(['agency_id' => $agency_id, 'collaborator_id' => $collaborator_id, 'is_leader' => $is_leader]);
        return $this->success('ok');
    }

    public function delAgencyUser($id, AgencyUser $agencyUser)
    {
        $agencyUser->where('id', $id)->delete();
        return $this->success('ok');
    }

    public function getAgencyUser(Request $request, $agency_id, AgencyUser $agencyUser)
    {
        $keyword = $request->get('keyword');
        $is_export = $request->get('is_export');

        $query = $agencyUser::query()->with('agency')->where('agency_user.agency_id', $agency_id)->join('collaborator as c', 'c.id', '=', 'agency_user.collaborator_id');
        $query->when($keyword, function ($query) use ($keyword) {
            $query->where('c.name', 'like', "%{$keyword}%");
        });

        $query->select('c.name', 'c.mobile', 'c.avatar', 'agency_user.*');
        if ($is_export) {
            $list = $query->get();
        } else {
            $list = $query->paginate();
        }

        foreach ($list as $item) {
            $item->num = Quota::where('agency_id', $agency_id)->where('collaborator_id', $item->collaborator_id)->sum('num');
            $item->patners = null;
            if (!isset($item->agency->partner_id)) {
                continue;
            }
            $item->patners = Partner::select('user_id', 'name', 'mobile', 'pic')->find($item->agency->partner_id);
        }

        if ($is_export) {
            return Excel::download(new AgencyUserExport($list), '分公司人员.xlsx');
        }
        return $this->success('ok', $list);
    }

    public function getAgencyByUser(Request $request, AgencyUser $agencyUser)
    {
        $no_page = $request->get('no_page');
        $collaborator_id = $request->get('collaborator_id');
        $agency_ids = $agencyUser->where('collaborator_id', $collaborator_id)->pluck('agency_id');

        $query = Agency::query()->whereIn('id', $agency_ids)->orderByDesc('id');
        if ($no_page) {
            $list = $query->get();
        } else {
            $list = $query->paginate();
        }
        return $this->success('ok', $list);
    }

    public function cities(Request $request)
    {
        $address = Province::with('cities')->get();
        return $this->success('ok', $address);
    }

    /**
     * 所有地区代理
     * @param Request $request
     */
    public function allAreaAgencies(Request $request)
    {
        $data = [];
        $provinces = Province::with('agencies:partner_id,pro_id', 'agencies.partner', 'cities:city_id,city_name,pro_id', 'cities.agencies.partner')->select('pro_id', 'pro_name')->get();
        foreach ($provinces as $province) {
            $arr = [];
            $arr['name'] = $province->pro_name;
            $province_c = [];
            foreach ($province->agencies as $agency) {
                if ($agency->partner) {
                    $province_c[] = $agency->partner->name;
                }
            }
            $arr['value']['province_c'] = $province_c;
            $city_agency = [];
            foreach ($province->cities as $city) {
                if (count($city->agencies)) {
                    foreach ($city->agencies as $agency) {
                        $city_arr = [];
                        if ($agency->partner) {
                            $city_arr['name'] = $city->city_name;
                            $city_arr['value'] = $agency->partner->name;
                            $city_agency[] = $city_arr;
                        }
                    }
                }
            }
            $arr['value']['city_c'] = $city_agency;
            $data[] = $arr;
        }
        return $this->success('ok', $data);
    }

    public function coaches(Request $request)
    {
        $status = $request->input('status', null);
        $coaches = Coach::with('partner:id,name,mobile')
            ->when($status != null, function ($query) use ($status) {
                $query->where('status', $status);
            })
            ->orderByDesc('id')
            ->paginate();
        return $this->success('ok', $coaches);
    }

    public function partnerUrls(Request $request)
    {
        //正式环境
        $data = [
            'partner' => [
                'url' => config('app.url') . '/api/h5/partner/official/auth',
                'qrcode' => 'https://image.fulllinkai.com/202304/26/dedf7aff9563d6856d8d27440b1c7c50.png',
            ],
            'coach' => [
                'url' => config('app.url') . '/api/h5/coach/official/auth',
                'qrcode' => 'https://image.fulllinkai.com/202304/26/9b038e6f31169257ca42a093dbe03be0.png',
            ],
            'finance' => [
                'url' => config('app.url') . '/api/h5/finance/official/auth',
                'qrcode' => 'https://image.fulllinkai.com/202305/08/62d5e8f0cb13d67da6bc889ec5dcdf61.png',
            ],
            'main_coach' => [
                'url' => config('app.url') . '/api/h5/wechat/user/auth?target_path=chiefCoachInfo',
                'qrcode' => 'https://image.fulllinkai.com/202305/25/chiefCoachInfo_bind_qrcode.svg',
            ],
            'customer_service_user' => [
                'url' => config('app.url') . '/api/h5/wechat/user/auth?target_path=serviceInfo',
                'qrcode' => 'https://image.fulllinkai.com/202305/25/serviceInfo_bind_qrcode.svg',
            ],
            'collaborator' => [
                'url' => config('app.url') . '/api/h5/wechat/user/auth?target_path=partnerInfo',
                'qrcode' => 'https://image.fulllinkai.com/202306/10/partnerInfo_bind_qrcode.svg',//todo::待生成合作商二维码
            ],
            'moderator' => [
                'url' => config('app.url') . '/api/h5/wechat/user/auth?target_path=emceeApplyFor',
                'qrcode' => 'https://image.fulllinkai.com/202306/29/c4f379f46fdc5165a6f2ddb344ee0f5d.png',//todo::待生成合作商二维码
            ],
        ];
        return $this->success('ok', $data);
    }

    public function audit(Request $request)
    {
        try {
            //获取参数
            $id = intval($request->get('id'));
            $type = $request->get('type');
            $data = $request->only(['status', 'refusal_reason']);

            if (!$id)
                throw new Exception('请选择要处理的申请');

            DB::beginTransaction();
            //根据类型获取审核模型
            $user = match ($type) {
                2 => new Coach(),
                4 => new Partner(),
                default => throw new Exception('操作类型错误'),
            };
            //查找申请信息
            $user = $user->where('status', 0)->findOrFail($id);

            //更新审核状态
            $data['audit_at'] = now();
            $user->update($data);

            //审核通过后加入服务用户表
            if ($data['status'] == 1) {
                //服务用户信息
                $partner = $user->{$type == 2 ? 'partner' : ''} ?? $user;
                //检查小伙伴是否绑定用户
                if (!$partner->user_id) {
                    $partner->user_id = $partner->wechat->user_id;
                    $partner->save();
                }
                //构建服务用户数据
                $serviceUserInfo = [
                    'name' => $partner->name,
                    'mobile' => $partner->mobile,
                    'user_id' => $partner->user_id
                ];
                //添加服务用户
                $serviceUser = $partner->service_user()->first();
                if (!$serviceUser) {
                    $serviceUser = $partner->service_user()->create($serviceUserInfo);
                }

                //添加对应角色
                $roleExist = $serviceUser->service_roles()->where('role_id', $type)->exists();
                if (!$roleExist) {
                    $roleData = ['user_id' => $partner->user_id];
                    $serviceUser->service_roles()->attach($type, $roleData);
                }
            }
            DB::commit();

            return $this->success('ok');
        } catch (ModelNotFoundException) {
            return $this->jsonResponse(1, '未找到要处理的申请');
        } catch (Exception $exception) {
            DB::rollBack();
            return $this->jsonResponse(1, $exception->getMessage());
        }
    }


    /**
     * 获取收益记录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function getIncomeCheckList(Request $request)
    {
        try {
            $status = $request->get('status', 0);
            $type = $request->get('type', 1);
            $is_export = $request->get('is_export');

            $query = PartnerCommission::query()->with(['user']);

            $query->when(strlen($status) > 0, function ($query) use ($status) {
                $query->where('status', $status);
            });

            $query->when(strlen($type) > 0, function ($query) use ($type) {
                $query->where('type', $type);
            });

            $query->orderByDesc('id');

            if ($is_export) {
                $list = $query->get();
            } else {
                $list = $query->paginate();
            }

            //导出数据
//            if($is_export){
//                if($list->isEmpty()){
//                    return $this->failure('暂无数据');
//                }
//                return Excel::download(new ContractExport($list), 'contract.xlsx');
//            }
            return $this->success('ok', $list);
        } catch (\Exception $e) {
            return $this->failure('getIncomeCheckList file:' . $e->getFile() . '|line:' . $e->getLine() . '|message:' . $e->getMessage());
        }
    }

    public function checkIncome(Request $request, $id)
    {
        try {
            DB::beginTransaction();
            $detail = PartnerCommission::findOrFail($id);
            if ($request->has('status')) {
                $detail->status = $request->input('status');
            }
            if ($request->has('reason')) {
                $detail->reason = $request->input('reason');
            }
            $detail->save();
            if ($request->status == 1) {//通过审核，修改钱包
                $wallet = $detail->user->wallets;
                if (!$wallet) {
                    $wallet = [
                        'balance' => config('app.env') == 'production' ? 0 : 10000,
                        'frozen_amount' => 0,
                        'withdrawn_amount' => 0,
                    ];
                    $wallet = $detail->user->wallets()->create($wallet);
                }
                $wallet->increment('balance', $detail->amount);
                //                $wallet->increment('withdrawn_amount', $detail->amount);
            }
            DB::commit();
            return $this->success('ok');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->failure('checkIncome file:' . $e->getFile() . '|line:' . $e->getLine() . '|message:' . $e->getMessage());
        }
    }
}
