<?php

namespace App\Http\Repositories;

use App\Helpers\UserHelper;
use App\Models\Factory_chemical;
use Illuminate\Support\Facades\Auth;

class FactoryChemicalRepository
{
    function __construct(protected Factory_chemical $fc, protected AuthRepository $auth) {}

    function getFactoryChem($company_id, $user)
    {
        $childcompany = $this->auth->getchildcompany($user);
        if ($company_id === $user->id) {
            return $this->fc->where('company_id', $company_id)
                ->where('now_weight', '>', 0)
                ->whereNotIn('custodian', $childcompany)
                ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
                ->orderby('created_at', 'desc')->get();
        } else {
            return $this->fc->where('custodian', $user->id)
                ->where('now_weight', '>', 0)
                ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
                ->orderby('created_at', 'desc')->get();
        }
    }

    function get3DFactoryChemArea($area_id)
    {
        return $this->fc
            ->select('cas_no', 'area_id', 'build_id', 'factory_id', 'custodian', 'chemical_id', 'serial_num')
            ->distinct('cas_no', 'state', 'conc')
            ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
            ->where('now_weight', '>', 0)
            ->where('area_id', $area_id)->get();
    }

    function get3DFactoryChemBuild($build_id)
    {
        return $this->fc
            ->select('cas_no', 'area_id', 'build_id', 'factory_id', 'custodian', 'chemical_id', 'serial_num')
            ->distinct('cas_no', 'state', 'conc')
            ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
            ->where('now_weight', '>', 0)
            ->where('build_id', $build_id)->get();
    }
    function get3DFactoryChemFloor($build_id, $floor)
    {
        return $this->fc
            ->join('factory_areas as area', 'area.id', '=', 'factory_chemicals.area_id')
            ->select('cas_no', 'area_id', 'build_id', 'factory_id', 'custodian', 'chemical_id', 'serial_num', 'area.floor as floor')
            ->distinct('cas_no', 'state', 'conc')
            ->with('chemical:id,cas_no,en_name,ch_name')
            ->where('now_weight', '>', 0)
            ->where('build_id', $build_id)
            ->where('floor', $floor)
            ->get();
    }
    function getDisposal($user)
    {
        $childcompany = $this->auth->getchildcompany($user);
        if (UserHelper::getCompanyId() === $user->id) {
            return $this->fc->onlyTrashed()->where('company_id', $user->id)
                ->whereNotIn('custodian', $childcompany)
                ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
                ->orderby('created_at', 'desc')->get();
        } else {
            return $this->fc->onlyTrashed()->where('custodian', $user->id)
                ->with('chemical:id,cas_no,en_name,ch_name', 'area:id,name', 'build:id,name', 'factories:id,name', 'custodian:id,contact_name')
                ->orderby('created_at', 'desc')->get();
        }
    }
    function getSearchChem($request, $user, $company_id)
    {
        $childcompany = $this->auth->getchildcompany($user);
        $query = $this->fc->query();
        if ($company_id === $user->id) {
            $query->where('company_id', $company_id)->whereNotIn('custodian', $childcompany);
        } else {
            $query->where('custodian', $user->id);
        }

        $searchFields = ['cas_no', 'custodian', 'factory_id', 'build_id', 'area_id'];

        foreach ($searchFields as $field) {
            if (!empty($request->$field)) {
                $query->where($field, 'like', '%' . $request->$field . '%');
            }
        }
        $query->with([
            'area:id,name',
            'build:id,name',
            'factories:id,name',
            'custodian:id,contact_name',
        ]);
        return $query->where('now_weight', '>', 0)->orderby('created_at', 'desc')->get();
    }
    function find($factoryChem_id)
    {
        return $this->fc->with([
            'doc_list' => function ($query) {
                $query->where('company_id', UserHelper::getCompanyId())
                    ->whereHas('doc', function ($q) {
                        $q->where('end_date', '>', now());
                    });
            },
            'chemical'
        ])->where('id', $factoryChem_id)->first();
    }
    //多筆查詢
    function manyFindFactoryChem($ids)
    {
        $items = $this->fc->with('chemical')->whereIn('id', $ids)->get()->keyBy('id');
        // 針對每筆 factory_chem 動態載入對應的 doc_list
        foreach ($items as $item) {
            $item->load(['doc_list' => function ($query) use ($item) {
                $query->where('company_id', UserHelper::getCompanyId())
                    ->whereRaw('conc_low::double precision <= ?', [$item->conc])
                    ->whereRaw('conc_up::double precision >= ?', [$item->conc])
                    ->orderByRaw('(conc_up::double precision - conc_low::double precision) ASC')
                    ->limit(1)
                    ->whereHas('doc', function ($q) {
                        $q->where('end_date', '>', now());
                    });
            }]);
        }
        return $items;
    }

    function haveArea($area_id)
    {
        return $this->fc->where('area_id', $area_id)->first();
    }

    function manyFind($data, $id)
    {
        return $this->fc->whereIn('id', $id)->update($data);
    }

    function copyData($id)
    {
        $factoryChem = $this->fc->find($id);
        return $factoryChem->replicate();
    }
    function getBottlesByOrderId($ordId)
    {
        return $this->fc->where('ord_id', $ordId)->get()->toArray();
    }
    function delBottle($ordId, array $data)
    {
        $deleteId = $this->fc->where('ord_id', $ordId)->whereNotIn('serial_num', $data)->pluck('id');
        $this->fc->whereIn('id', $deleteId)->delete();
        return $deleteId;
    }
    function canDestory($id): bool
    {
        $factoryChem = $this->fc->where('ord_id', $id)->get();
        foreach ($factoryChem as $chem) {
            if ($chem->ori_weight !== $chem->now_weight) {
                return false;
            }
        }
        return true;
    }
    function store($data)
    {
        $fcId = $this->fc->create($data);

        return $fcId;
    }
    function update($data, $id)
    {
        unset($data['add_date']);
        unset($data['bottle_type']);
        unset($data['supplier_id']);
        unset($data['brand']);
        unset($data['ord_type']);
        unset($data['ship_no']);
        unset($data['bottleCount']);
        unset($data['weight']);
        unset($data['remark']);
        unset($data['bottles']);
        unset($data['blends']);
        unset($data['factory_chem']);
        unset($data['chem_mix']);
        unset($data['id']);
        unset($data['oriblends']);
        unset($data['unit']);
        unset($data['packag_unit']);
        return $this->fc->where('id', $id)->update($data);
    }

    function destory($id)
    {
        return $this->fc->where('ord_id', $id)->forceDelete();
    }

    function softdelete($id)
    {
        return $this->fc->whereIn('id', $id)->delete();
    }

    function serachSoftDelete($id)
    {
        return $this->fc->withTrashed()->find($id);
    }
}
