<?php

/**
 * v2 缴费模块
 */
namespace app\em\controller;
use app\admin\controller\Base;
use app\admin\model\ElectricMeter;
use app\em\model\EmAccount;
use app\em\model\EmCert;
use app\em\model\EmInvoice;
use app\em\model\EmInvoiceHistory;
use app\em\model\EmPayment;
use app\em\model\EmPaymentInvoice;
use app\em\model\EmPaymentInvoiceBalance;
use app\em\model\EmPaymentReceipt;
use app\em\model\Staff;
use app\em\validate\AddPaymentValidate;
use think\Exception;
use think\facade\Request;
use think\facade\Session;

class Payment extends Base
{
    const PAYMENT_INIT_CODE = 0 ;            //状态码
    const PAYMENT_PARTIAL_CODE = 1;          //状态码
    const PAYMENT_FULL_CODE = 2;             //状态码
    const PAYMENT_STATUS_INDEX = 0;          //索引位置

    //缴费单列表
    public function index(){
        $map=[];
        //权限检测
        $user = Session::get('user');
        if(!$user['is_admin']){
            $permissionData=check_data();
            if($permissionData){
                $map[]=$permissionData;
            }
        }
        $search_text = Request::get('search_text');
        $search_type = Request::get('search_type');
        if($search_text){
            switch ($search_type) {
                case '1':
                    $this->assign('search_text',$search_text);

                    if(strstr($search_text,',')){
                        $searchArr = explode(',',$search_text);
                        $map[]=['pay.payment_id','in',$searchArr];
                    } else {
                        $map[]=['pay.payment_id','like',"%$search_text%"];
                    }
                    $this->assign('search_type',$search_type);
                    break;
                case '2':
                    $this->assign('search_text',$search_text);
                    $map[]=['epi.invoice_id','like',"%$search_text%"];
                    $this->assign('search_type',$search_type);
                    break;
                case '3':
                    $this->assign('search_text',$search_text);
                    $map[]=['em.em_numb','like',"%$search_text%"];
                    $this->assign('search_type',$search_type);
                    break;
            }
        }else{
            $this->assign('search_type','');
            $this->assign('search_text','');
        }
        //区域
        $area_id = Request::get('area_id');
        if($area_id){
            $map[] = ['station.area_id','=',$area_id];
            $this->assign('area_id',$area_id);
        }else{
            $this->assign('area_id','');
        }
        //创建时间查询条件
        $dateStart = strtotime(Request::get('date_start'));
        $dateEnd = strtotime(Request::get('date_end'));
        //区间查询
        if( !empty($dateStart) && !empty($dateEnd) ){
            $map[] = ['pay.pay_date','between',[$dateStart,$dateEnd]];
            $this->assign('date_start',Request::get('date_start'));
            $this->assign('date_end',Request::get('date_end'));
        } elseif (!empty($dateStart) && empty($dateEnd)){
            $map[] = ['pay.pay_date','>',$dateStart];
            $this->assign('date_start',Request::get('date_start'));
            $this->assign('date_end','');
        } elseif (empty($dateStart) && !empty($dateEnd)){
            $map[] = ['pay.pay_date','<',$dateEnd];
            $this->assign('date_end',Request::get('date_end'));
            $this->assign('date_start','');
        }else{
            $this->assign('date_start','');
            $this->assign('date_end','');
        }
        $page =Request::param('page')?Request::param('page'):1;
        $limit = Request::param('limit')?Request::param('limit'):10;
        $region=new ElectricMeter();
        $data = (new EmPayment())->getPaymentList($map,$page,$limit);
        $PaymentCount = (new EmPayment())->getPaymentCount($map);
        if(Request::param('page')){
            return ['code'=>0,'msg'=>'','count'=>$PaymentCount,'data'=>$data];
        }
        $this->assign('regions',getTree($region->regions()));
        return $this->fetch();

    }

    //批量生成缴费单
    public function createAll(){
        $ids = Request::param('ids');

        //todo:优先锁定ids的状态,不能再次生成缴费单


        //首先查询这些账单是否具备生成条件
        $eiModel = new EmInvoice();
        $invs = $eiModel->where('payment_balance','neq',0)
                        ->where(['invoice_id'=>$ids])->order('invoice_id asc')->select();

        if($invs->isEmpty()) {
            $invIds = implode(',',$ids);
            return json(['status'=>0,'message'=>'账单号: '.$invIds.' 不能重复生成缴费单!']);
        }
        //过滤不可以生成缴费单的账单ID
        $idsArr = [];
        foreach ($invs as $inv){
            //未生成缴费或已挂起
            if($inv->payment_amount >= $inv->payment_balance){
                //是否已挂起
                $paymentField = EmPaymentInvoice::field('payment_id')
                                                ->where('invoice_id','=',$inv->invoice_id)
                                                ->order('create_time desc')->find();
                if($paymentField){
                    //找到关联的缴费单
                    $payment = EmPayment::where('payment_id','=',$paymentField->payment_id)->find();

                    //如果缴费单并未缴费
                    if($payment->amount == 0){
                        $message = '账单号: '.$inv->invoice_id.' 已经挂起,无法生成缴费单';
                        return json(['status'=>0,'message'=>$message]);
                    } else {
                        $idsArr[] = $inv->invoice_id;
                    }
                } else {
                    $idsArr[] = $inv->invoice_id;
                }
            }
        }
        $ids = $idsArr;

        //如果没有生成过缴费单,则生成缴费单
        //1.创建缴费号
        $paymentId = $this->getPaymentId();
        //2.将缴费号与账单号写入关联表
        $paymentInvoiceArr = [];
        foreach ($ids as $inv_id){
            $paymentInvoiceArr [] = [
                'payment_id' => $paymentId,
                'invoice_id' => $inv_id
            ];
        }
        $model = new EmPaymentInvoice();
        if(!$model->saveAll($paymentInvoiceArr)){
            throw new Exception('保存账单与缴费关联数据失败');
        };

        $account = (new EmAccount())->getIdByInvoiceID($paymentInvoiceArr[0]['invoice_id']);

        //3.将账单数据汇总写入缴费表
        $pData  = [];
        $pData['amount'] = 0;
        $pData['payment_id'] = $paymentId;
        $pData['status'] = 0;
        $pData['account_id'] = $account->account_id;
        $pData['balance'] = $pData['amount'];

        if((new EmPayment())->save($pData)){
            return json(['status'=>1,'message'=>'已创建缴费单']);
        } else {
            throw new Exception('创建缴费信息失败');
        }
    }

    //预付费表先缴费
    public function create(){
        $em_id = Request::param('em_id');
        if(!(new Em())->checkEmcomplete($em_id)){
            $this->error('电表信息不完整,需要补充基础信息','/em');
        }
        $payment  =  new EmPayment();
        $payment->payment_id = $this->getPaymentId();

        //当前用户
        $user  =  Session::get('user');
        $this->assign('uid',$user['user_id']);
        $this->assign('staffs',(new Staff())->getStaffs($user['is_admin']));

        $this->assign('em_id',$em_id);
        $this->assign('payment',$payment);
        return $this->fetch();
    }

    //更新缴费数据 即保存缴费 记录一次缴费
//    public function update(){
//        $data = Request::post();
//
//        //更新缴费信息
//        $payment = EmPayment::get(['payment_id'=>$data['payment_id']]);
//        $payment->amount = $data['paid_totle'];     //记录凭证金额
//        $payment->staff_id = $data['staff_id'];
//        //等待审核1,2已审核 1阶段暂忽略
//        //$payment->status = 1;
//        $payment->status = 2;
//        $payment->save();
//
//        //更新账单状态
//        //1.查询所有账单
//        $invArr = [];
//        foreach ($data['paid'] as $key => $item) {
//            $invArr['invoice_id'] = $key;
//            $invArr['paid_amount'] = $item['paid_amount'];
//        }
//        /*
//         * 循环查询账单 并计算balance的数值 更新balance,并将当前的状态,同步到历史数据一份进行销账的追踪
//         * 通过与balance的计算结果比较 如果balance=0,则账单状态更新为已缴费 如果不为0则更新为部分缴费
//         * 账单与缴费凭证关系的建立 通过缴费单与凭证的关联关系获取,显示在账单详情中
//         */
//        foreach ($invArr as $item){
//            $inv = EmInvoice::get(['invoice_id'=>$item['invoice_id']]);
//
//            $balance = $inv->payment_balance - $inv['paid_amount'];
//
//            //计算状态
//            if($balance == 0){
//                $inv->status = setInvoiceStatus($inv->status,self::PAYMENT_FULL_CODE,self::PAYMENT_STATUS_INDEX);
//            } else {
//                $inv->status = setInvoiceStatus($inv->status,self::PAYMENT_PARTIAL_CODE,self::PAYMENT_STATUS_INDEX);
//            }
//
//            $inv->payment_balance = $balance;
//
//            //更新账单信息
//            $inv->save();
//            //保存销账明细,复制当前对象数据 到history表
//
//            $invHistory = new EmInvoiceHistory();
//
//            if(!$invHistory->save($inv->toarray())){
//                throw new Exception('保存销账明细错误!');
//            } else {
//                return json(['status'=>1,'message'=>'缴费成功!']);
//            }
//        }
//
//    }

    //缴费单详情
    public function detail(){
        $payment_id = Request::param('payment_id');
        $epModel = new EmPayment();
        //查询缴费单基本信息
        $payment = $epModel->where('payment_id','=',$payment_id)->find();

        switch ($payment->status){
            case 0:
                $payment->statusTitle = '未缴费';
                break;
            case 1:
                $payment->statusTitle = '已缴费';
                break;
            case 2:
                $payment->statusTitle = '已上传发票';
                break;
            case 3:
                $payment->statusTitle = '凭证完整';
                break;
            case 4:
                $payment->statusTitle = '已审核';
                break;
        }

        $this->assign('payment',$payment);
        //查询账单信息
        $invs = $epModel->getinvsInfo($payment->payment_id);

        foreach ($invs as $inv){
            if($inv->payment_balance == 0){
                $inv->paid_amount = $inv->payment_amount;
            } else {
                $inv->paid_amount = $inv->payment_amount - $inv->payment_balance;
            }
        }

        $this->assign('invs',$invs);

        //实缴金额
        $amount = EmCert::where('payment_id','=',$payment_id)->sum('amount');
        if($payment->mark){
            if($payment->balance == 0){
                $amount = $payment->amount;
            } else {
                $amount = $payment->amount - $payment->balance;
            }
        }
        $this->assign('payment_sum_amount',$amount);
        //查询凭证信息
        $receipts = (new EmPaymentReceipt)->getPaymentReceiptByPaymentId($payment_id);

        if(!$receipts)  $receipts = [];
        foreach ($receipts as &$receipt){
            $receipt->file_src = trim($receipt->file_src,'.');
        }
        $this->assign('receipts',$receipts);

        //员工列表
        $user  =  Session::get('user');
        $this->assign('staffs',(new Staff())->getStaffs($user['is_admin']));

        return $this->fetch();
    }

    //生成缴费单号
    private function getPaymentId(){
        $payment = EmPayment::field('id')->order('id desc,create_time desc')->find();
        if(!$payment) $id = 1;
        else $id = $payment->id + 1;
        return "JF".date('Ymd').zero($id);
    }

    //更新状态
    public function updateStatus($payment_id){
        //变更为已缴费
        $paymentModel = EmPayment::get(['payment_id'=>$payment_id]);
        $paymentModel->status = 1;
        $paymentModel->save();
    }

    /**
     * 保存缴费单
     * 1.保存缴费人信息
     * 2.保存消费状态
     */
    public function store(){
        $data = Request::post();

        //如果是预付费缴费 充值卡
        if(isset($data['em_id'])){
            $validate = new AddPaymentValidate();
            if(!$validate->scene('s2')->check($data))
                return json(['status'=>0,'message'=>$validate->getError()]);
            $paymentModel = new EmPayment;
            $paymentModel->payment_type = 4;

            //更新账户
            $account = (new Account());
            $accountId = $account->getAccountId($data['em_id']);
            $paymentModel->payment_id = $this->getPaymentId();
            $paymentModel->account_id = $accountId;
            $paymentModel->balance = $data['amount'];
            $paymentModel->save($data);

        //如果是后付费
        } else {
            $certs = EmCert::where('payment_id','=',$data['payment_id'])->select();

            $receipts = EmPaymentReceipt::where('payment_id','=',$data['payment_id'])->select();

            $paymentModel = EmPayment::where('payment_id','=',$data['payment_id'])->find();

            //更新实缴金额
            $amount  = 0 ;
            foreach ($certs as $cert){
                $amount += $cert->amount;
            }
            $paymentModel->amount = $paymentModel->balance = $amount;
            //判断是否已经上传缴费凭证信息
            if(!$certs->isEmpty() && !$receipts->isEmpty()){
                $paymentModel->status = 3; //代表已经缴费
            } else if(!$certs->isEmpty()){
                $paymentModel->status = 1;
            } else if(!$receipts->isEmpty()){
                $paymentModel->status = 2;
            }
            $paymentModel->staff_id = $data['staff_id'];
            $paymentModel->save();
        }
        return json(['status'=>1,'message'=>'保存缴费信成功']);
    }

    //审核通过开始销账
    public function confirm(){
        $payment_id = Request::param('payment_id');

        //判断是否具备审核条件
        $amount = EmCert::where('payment_id','=',$payment_id)->sum('amount');
        $paymentModel = EmPayment::get(['payment_id' => $payment_id]);

        //账单实缴金额保存到账单里面
        if($amount > 0 && $paymentModel->status == 3) {

            $paymentModel->pay_date = date('Y:m:d H:i:s',time());
            $paymentModel->amount = $paymentModel->balance = $amount;
            $paymentModel->save();
            //销账
            (new Account())->upAmount($paymentModel->account_id,$paymentModel->amount);

            $result =  (new Invoice())->writeOffFromPayment($paymentModel->account_id,$payment_id);
            return json(['status'=>1,'message'=>$result]);
        }
        return json(['status'=>0,'message'=>'不满足审核条件']);
    }

    /**
     * 显示缴费详情
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function payDetail(){
        $invoice_id = Request::param('invoice_id');
        $eibs = EmPaymentInvoiceBalance::where('invoice_id','=',$invoice_id)
                                        ->order('payment_id asc')->select();
        $this->assign('data',$eibs);
        return $this->fetch();
    }
}