<?php 

namespace App\Services; 

use App\OwnerAreaReport;
use App\OwnerBillReport;
use App\Services\common\QueryService;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;

Class OwnerAreaReportService
{
    /**
     * @param Builder $builder
     * @param array $params
     * @return Builder
     */
    private function query(Builder $builder, array $params)
    {
        $columnQueryRules = [
            'counting_month_start' => ['alias' => 'counting_month', 'startDate' => '-01'],
            'counting_month_end' => ['alias' => 'counting_month', 'endDate' => '-31'],
            'owner_id' => ['multi' => ','],
        ];
        if ($params["customer_id"] ?? false){
            $builder->whereHas('owner',function ($query)use(&$params){
                /** @var Builder $query*/
                $query->where("customer_id",$params["customer_id"]);
                unset($params["customer_id"]);
            });
        }
        return app(QueryService::class)->query($params, $builder, $columnQueryRules);
    }

    public function paginate(array $params, array $withs = null)
    {
        $areas = OwnerAreaReport::query()->orderByDesc('id');
        if ($withs)$areas->with($withs);
        return $this->query($areas,$params)->paginate($params["paginate"] ?? 50);
    }


    /**
     * 面积变更会去对比账单更新账单 考虑到后续账单变更有多种渠道此处加排他锁
     *
     * @param array $params
     * @param array $values
     * @return int
     */
    public function update(array $params, array $values):bool
    {
        DB::beginTransaction();
        $area = $this->query(OwnerAreaReport::query(),$params)->with("ownerStoragePriceModel")->lockForUpdate()->first();
        try{
            if ($values["accounting_area"] ?? null && $area->accounting_area != $values["accounting_area"]){
                $report = OwnerBillReport::query()->lockForUpdate()->where("owner_id",$area->owner_id)
                    ->where("counting_month",'like',$area->counting_month."%")->first();
                if ($report){
                    if (!$area->ownerStoragePriceModel)return false;
                    $diff = $area->accounting_area - $values["accounting_area"];
                    $diffAmount = app("OwnerStoragePriceModelService")->calculationAmount($area->ownerStoragePriceModel, $diff, $area->owner_id, $area->counting_month);
                    if ($diffAmount != 0){
                        $up = ["initial_fee"=>$report->initial_fee - $diffAmount];
                        if ($report->confirm_fee !== null)$up["difference"] = $up["initial_fee"] - $report->confirm_fee;
                        $report->update($up);
                    }
                }
            }
            $area->update($values);
            DB::commit();
            return true;
        }catch (\Exception $e){
            DB::rollBack();
            return false;
        }
    }

    public function get(array $params, array $withs = null)
    {
        $query = OwnerAreaReport::query()->orderByDesc('id');
        if ($withs)$query->with($withs);
        return $this->query($query,$params)->get();
    }

}