<?php

namespace App\Http\Models\Project;

use App\Http\Models\Cluster\Lot;
use App\Http\Models\Customer\CustomerLot;
use Carbon\Carbon;
use DB;
use Illuminate\Database\Eloquent\Model;

/**
 * @property string     $number
 * @property int        $template_id
 * @property string     $title
 * @property string     $subject
 * @property Date       $date
 * @property string     $params
 * @property int        $created_at
 * @property int        $updated_at
 */
class SpkProjects extends Model
{
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'spk_projects';

    /**
     * The primary key for the model.
     *
     * @var string
     */
    protected $primaryKey = 'id';

    /**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = [
        'title',
        'number',
        'dest_name',
        'date',
        'subject',
        'customer_lot_id',
        'note',
        'created_by_user_id',
        'approved_by_user_id',
        'received_by_user_id'
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [

    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = [
        'date', 'created_at', 'updated_at'
    ];

    /**
     * Indicates if the model should be timestamped.
     *
     * @var boolean
     */
    public $timestamps = true;

    // Map Schema...
    public static function mapSchema($params = [], $user = [])
    {
        $model = new self;

        return [
            'id' => ['alias' => $model->table.'.id', 'type' => 'int'],
            'title' => ['alias' => $model->table.'.title', 'type' => 'string'],
            'number' => ['alias' => $model->table.'.number', 'type' => 'string'],
            'dest_name' => ['alias' => $model->table.'.dest_name', 'type' => 'string'],
            'date' => ['alias' => $model->table.'.date', 'type' => 'string'],
            'subject' => ['alias' => $model->table.'.subject', 'type' => 'string'],
            'customer_lot_id' => ['alias' => $model->table.'.customer_lot_id', 'type' => 'int'],
            'note' => ['alias' => $model->table.'.note', 'type' => 'string'],
            'created_by_user_id' => ['alias' => $model->table.'.created_by_user_id', 'type' => 'int'],
            'approved_by_user_id' => ['alias' => $model->table.'.approved_by_user_id', 'type' => 'int'],
            'received_by_user_id' => ['alias' => $model->table.'.received_by_user_id', 'type' => 'int'],
            'created_at' => ['alias' => $model->table.'.created_at', 'type' => 'string'],
            'updated_at' => ['alias' => $model->table.'.updated_at', 'type' => 'string']
        ];
    }
    // Scopes...

    // Functions ...

    // Relations ...

    public static function datatables($start, $length, $order, $dir, $search, $filter = '', $session = [])
    {
        $totalData = self::count();

        $_select = [];
        foreach(array_values(self::mapSchema()) as $select) {
            $_select[] = $select['alias'];
        }

        $qry = self::select($_select)->addSelect('clusters.name as cluster_name')->addSelect('lots.unit_number as unit_number')
        ->addSelect('lots.block as unit_block')->addSelect('users.name as customer_name')
                    ->join('customer_lots', 'customer_lots.id', '=', 'spk_projects.customer_lot_id')
                    ->join('customers', 'customers.id', '=', 'customer_lots.customer_id')
                    ->join('users', 'users.id', '=', 'customers.user_id')
                    ->join('lots', 'lots.id', '=', 'customer_lots.lot_id')
                    ->join('clusters', 'clusters.id', '=', 'lots.cluster_id');

        if ((isset($session['_role_id']) && $session['_role_id'] > 1) && (isset($session['_cluster_id']) && $session['_cluster_id'] > 0)) {
            $qry->where('lots.cluster_id', $session['_cluster_id']);
        }

        $totalFiltered = $qry->count();

        if (empty($search)) {

            if ($length > 0) {
                $qry->skip($start)
                    ->take($length);
            }

            foreach ($order as $row) {
                $qry->orderBy($row['column'], $row['dir']);
            }

        } else {
            foreach (array_values(self::mapSchema()) as $key => $val) {
                if ($key < 1) {
                    $qry->whereRaw('('.$val['alias'].' LIKE \'%'.$search.'%\'');
                } else if (count(array_values(self::mapSchema())) == ($key + 1)) {
                    $qry->orWhereRaw($val['alias'].' LIKE \'%'.$search.'%\')');
                } else {
                    $qry->orWhereRaw($val['alias'].' LIKE \'%'.$search.'%\'');
                }
            }

            $totalFiltered = $qry->count();

            if ($length > 0) {
                $qry->skip($start)
                    ->take($length);
            }

            foreach ($order as $row) {
                $qry->orderBy($row['column'], $row['dir']);
            }
        }

        return [
            'data' => $qry->get(),
            'totalData' => $totalData,
            'totalFiltered' => $totalFiltered
        ];
    }

    public static function createOrUpdate($params, $method, $request)
    {
        DB::beginTransaction();
        $filename = null;

        if (isset($params['_token']) && $params['_token']) {
            unset($params['_token']);
        }

        if (isset($params['id']) && $params['id']) {
            $id = $params['id'];
            unset($params['id']);

            $update = self::where('id', $id)->update($params);
            DB::commit();
            return response()->json([
                'status' => 'success',
                'message' => 'Data Berhasil Diubah!'
            ]);
        }

        $params['title'] = (isset($params['title']) && $params['title']) ? $params['title'] : 'Surat Perintah Kerja';
        $params['subject'] = (isset($params['subject']) && $params['subject']) ? $params['subject'] : 'Pembangunan Unit Rumah';
        $params['dest_name'] = (isset($params['dest_name']) && $params['dest_name']) ? $params['dest_name'] : 'Project Department';
        $params['created_by_user_id'] = session()->get('_id');
        $params['approved_by_user_id'] = 0;
        $params['received_by_user_id'] = 0;
        $insert = self::create($params);

        if ($insert) {
            //Update Status Booking
            CustomerLot::where('id', $params['customer_lot_id'])->update([
                'status' => 5
            ]);

            $lot_id = CustomerLot::where('id', $params['customer_lot_id'])->value('lot_id');
            //Update Status Lot
            Lot::where('id', $lot_id)->update([
                'lot_status' => 5
            ]);
        }

        DB::commit();
        return response()->json([
            'status' => 'success',
            'message' => 'Data Berhasil Disimpan'
        ]);
    }

    public static function getPaginatedResult($params)
    {
        $paramsPage = isset($params['page']) ? $params['page'] : 0;

        unset($params['page']);

        $_select = [];
        foreach(array_values(self::mapSchema()) as $select) {
            $_select[] = $select['alias'];
        }

        $db = self::select($_select)
                ->addSelect('inventory_units.name as unit_name')
                ->join('inventory_units', 'inventory_units.id', '=', 'inventories.unit_id');

        if ($params) {
            foreach (array($params) as $k => $v) {
                foreach (array_keys($v) as $key => $row) {
                    if (isset(self::mapSchema()[$row])) {
                        if (is_array(array_values($v)[$key])) {
                            if ($this->operators[array_keys(array_values($v)[$key])[$key]] != 'like') {
                                $db->where(self::mapSchema()[$row]['alias'], $this->operators[array_keys(array_values($v)[$key])[$key]], array_values(array_values($v)[$key])[$key]);
                            } else {
                                if (self::mapSchema()[$row]['type'] === 'int') {
                                    $db->where(self::mapSchema()[$row]['alias'], array_values($v)[$key]);
                                } else {
                                    $db->where(self::mapSchema()[$row]['alias'], 'like', '%'.array_values($v)[$key].'%');
                                }
                            }
                        } else {
                            if (self::mapSchema()[$row]['type'] === 'int') {
                                $db->where(self::mapSchema()[$row]['alias'], array_values($v)[$key]);
                            } else {
                                $db->where(self::mapSchema()[$row]['alias'], 'like', '%'.array_values($v)[$key].'%');
                            }
                        }
                    }
                }
            }
        }

        $countAll = $db->count();
        $currentPage = $paramsPage > 0 ? $paramsPage - 1 : 0;
        $page = $paramsPage > 0 ? $paramsPage + 1 : 2;
        $nextPage = env('APP_URL').'/inventories?page='.$page;
        $prevPage = env('APP_URL').'/inventories?page='.($currentPage < 1 ? 1 : $currentPage);
        $totalPage = ceil((int)$countAll / 10);

        // $db->orderBy($model->table.'.fullname', 'asc');
        $db->skip($currentPage * 10)
           ->take(10);

        return response()->json([
            'nav' => [
                'totalData' => $countAll,
                'nextPage' => $nextPage,
                'prevPage' => $prevPage,
                'totalPage' => $totalPage
            ],
            'data' => $db->get()
        ]);
    }

    public static function getById($id, $params = null)
    {
        $data = self::where('id', $id)->with('customerLot.lot')
                    ->first();

        return response()->json($data);
    }

    public static function getAllResult($params)
    {
        unset($params['all']);

        $db = self::select(array_keys(self::mapSchema()));

        if ($params) {
            foreach (array($params) as $k => $v) {
                foreach (array_keys($v) as $key => $row) {
                    if (isset(self::mapSchema()[$row])) {
                        if (is_array(array_values($v)[$key])) {
                            if ($this->operators[array_keys(array_values($v)[$key])[$key]] != 'like') {
                                $db->where(self::mapSchema()[$row], $this->operators[array_keys(array_values($v)[$key])[$key]], array_values(array_values($v)[$key])[$key]);
                            } else {
                                $db->where(self::mapSchema()[$row], 'like', '%'.array_values($v)[$key].'%');
                            }
                        } else {
                            if (self::mapSchema()[$row]['type'] === 'int') {
                                $db->where(self::mapSchema()[$row]['alias'], array_values($v)[$key]);
                            } else {
                                $db->where(self::mapSchema()[$row]['alias'], 'like', '%'.array_values($v)[$key].'%');
                            }
                        }
                    }
                }
            }
        }

        return response()->json([
            'data' => $db->get()
        ]);
    }

    public static function generatePdf($id)
    {
        $spkProject = self::findOrFail($id);
        $item = [
            'number_project' => $spkProject->number,
            'from' => $spkProject->customerLot->lot->cluster->name,
            'date' => Carbon::parse($spkProject->date)->translatedFormat('d F Y'),
            'title' =>$spkProject->title,
            'customer_name' => $spkProject->customerLot->customer->user->name,
            'lot_number' => $spkProject->customerLot->lot->block .' - '. $spkProject->customerLot->lot->unit_number,
            'building_area' => $spkProject->customerLot->lot->building_area,
            'surface_area' => $spkProject->customerLot->lot->surface_area,
            'note' => isset($spkProject->note) && $spkProject->note ? $spkProject->note : '-',
            'status' => $spkProject->customerLot->generalStatus ? $spkProject->customerLot->generalStatus->name : '-',
        ];

        return $item;
    }

    public function customerLot()
    {
        return $this->belongsTo(CustomerLot::class);
    }

    public function spk_project_additionals()
    {
        return $this->hasMany(SpkProjectAdditionals::class, 'spk_project_id');
    }
}
