<?php

namespace App\Models;

use App\Notifications\SendWhenStaffCollect;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\Traits\LogsActivity;

class CollectSpend extends Model
{
    //
    use SoftDeletes;
    use LogsActivity;

    protected static $logAttributes = ['*'];
    const COLLECT = 1;
    const SPEND = 2;

    const MONEY = 1;
    const BANK = 2;
    protected $fillable = [
        'collect',
        'spend',
        'status',
        'user_id',
        'owner_id',
        'room_id',
        'amount',
        'type_action',
        'type',
        'note',
        'created_at',
        'updated_at',
        'deleted_at',
        'date_action',
        'payment_method',
        'hostel_id',
        'money_info_id',
        'name',
        'hostel_name',
        'room_name',
        'code',
        'money_info_name',
        'receiver',
        'transaction_id',
        'payer',
        'contract_id',
        'is_deposit',
        'reserve_id',
        'money_info_type',
        'type_purpose',
        'is_statistic',
        'is_return_deposit',
        'type_collect_id',
        'is_allow_cycle'
    ];

    protected $dates = [
        'created_at',
        'updated_at',
        'date_action'
    ];

    public static function boot()
    {
        parent::boot();
        static::creating(function ($item) {

        });
        static::created(function ($item) {

            $userCurrent = null;
            if (auth('backend')->check()) {
                $userCurrent = auth('backend')->user();
                $item->user_id = $userCurrent->id;
                if ($userCurrent->type == User::OWNER) {
                    $item->owner_id = $userCurrent->id;
                } else {
                    $item->owner_id = $userCurrent->staff_owner_id;
                }
            } else {
                try {
                    $user = \JWTAuth::parseToken()->toUser();
                    if ($user) {
                        $userCurrent = $user;
                        $item->user_id = $user->id;
                        if ($user->type == User::OWNER) {
                            $item->owner_id = $user->id;
                        } else {
                            $item->owner_id = $user->staff_owner_id;
                        }
                    }
                } catch (\Exception $exception) {

                }
            }

            if (empty($userCurrent)) {
                if ($item->hostel) {
                    $item->owner_id = $item->hostel->owner_id;
                }
            }

            $moneyInfoId = $item->money_info_id;

            $moneyInfo = MoneyInfo::find($moneyInfoId);

            $hostelId = $item->hostel_id;
            $roomId = $item->room_id;
            $contractId = $item->contract_id;
            $contract = Contract::find($contractId);

            $note = $item->name;

            $hostelName = null;
            $roomName = null;
            $moneyInfoName = null;
            $moneyInfoType = MoneyInfo::VOUCHER_OTHER;

            $hostel = Hostel::find($hostelId);
            $room = Room::find($roomId);


            if ($hostel) {
                $hostelName = $hostel->name;
            }

            if ($room) {
                $roomName = $room->name;
            }

            $name = $item->name;
            if ($moneyInfo) {
                if (empty($contractId)) {
                    $contractId = $moneyInfo->contract_id;
                    $contract = Contract::find($contractId);
                }
                $moneyInfoName = $moneyInfo->name;
                $moneyInfoType = $moneyInfo->type;
                if ($moneyInfoType == MoneyInfo::VOUCHER_ROOM_PRICE || $moneyInfoType == MoneyInfo::VOUCHER_CONTRACT) {
                    $moneyDetails = MoneyDetail::where('money_info_id', $moneyInfo->id)->orderBy('id')->get();
                    if ($moneyDetails->count() > 0) {
                        $startDate = $moneyDetails->first()->start_date;
                        $endDate = $moneyDetails->last()->end_date;

                        if (!empty($startDate) && !empty($endDate)) {
                            $startDateName = Carbon::createFromFormat('Y-m-d', $startDate)->format('d/m/Y');
                            $endDateName = Carbon::createFromFormat('Y-m-d', $endDate)->format('d/m/Y');
                            $name = 'Thu tiền phòng từ ' . $startDateName . ' đến ' . $endDateName;
                        }
                    }
                } else {
                    if (!empty($moneyInfo->date_action)) {
                        $name = 'Thu tiền dịch vụ tháng ' . $moneyInfo->date_action->format('m/Y');
                    } else {
                        $name = 'Thu tiền dịch vụ';
                    }
                }
            } else {
                if ($item->is_deposit == true) {
                    $moneyInfoType = MoneyInfo::VOUCHER_DEPOSIT;
                }
            }

            if ($name != $item->name) {
                $item->name = $name;
                $note = $name;
            }

            if (empty($note)) {
                $note = $item->note;
            }


            if ($item->type == CollectSpend::COLLECT) {
                if ($moneyInfo) {
                    if ($item->hostel) {
                        $type = null;
                        if (in_array($moneyInfo->type, [
                            MoneyInfo::VOUCHER_ROOM_PRICE,
                            MoneyInfo::VOUCHER_CONTRACT
                        ])) {
                            $type = TypeCollect::query()
                                ->where('type', TypeCollect::ROOM_PRICE)
                                ->where('owner_id', $item->hostel->owner_id)
                                ->first();

                        } else if ($moneyInfo->type == MoneyInfo::VOUCHER_DEPOSIT) {
                            $type = TypeCollect::query()
                                ->where('type', TypeCollect::DEPOSIT)
                                ->where('owner_id', $item->hostel->owner_id)
                                ->first();
                        } else if ($moneyInfo->type == MoneyInfo::VOUCHER_SERVICE) {
                            $type = TypeCollect::query()
                                ->where('type', TypeCollect::SERVICE)
                                ->where('owner_id', $item->hostel->owner_id)
                                ->first();
                        }

                        if (!empty($type)) {
                            $item->type_collect_id = $type->id;
                        }
                    }
                } else {
                    if ($item->hostel) {
                        if ($item->is_deposit == true) {
                            $type = TypeCollect::query()
                                ->where('type', TypeCollect::DEPOSIT)
                                ->where('owner_id', $item->hostel->owner_id)
                                ->first();
                            if (!empty($type)) {
                                $item->type_collect_id = $type->id;
                            }
                        }
                    }
                }


                if (!$item->is_deposit) {

                    if ($moneyInfo) {
                        $itemStats = StatisticMonth::query()->where('money_info_id', $moneyInfo->id)
                            ->whereRaw('current_paid < amount')
                            ->get();
                        $collect = $item->amount;

                        if ($itemStats->count() > 0) {
                            foreach ($itemStats as $itemStat) {
                                if ($collect > 0) {
                                    $paid = $itemStat->current_paid + $collect;
                                    if ($paid > $itemStat->amount) {
                                        $collect = $paid - $itemStat->amount;
                                        $logCollect = $itemStat->amount - $itemStat->current_paid;
                                        $paid = $itemStat->amount;
                                    } else {
                                        $logCollect = $collect;
                                        $collect = 0;
                                    }
                                    if ($logCollect > 0) {
                                        StatisticLog::query()->updateOrCreate([
                                            'collect_spend_id' => $item->id,
                                            'statistic_month_id' => $itemStat->id,
                                        ], [
                                            'amount' => $logCollect,
                                            'month' => $itemStat->month,
                                            'year' => $itemStat->year,
                                            'type' => CollectSpend::COLLECT,
                                            'hostel_id' => $itemStat->hostel_id,
                                            'room_id' => $itemStat->room_id,
                                            'collect_spend_id' => $item->id,
                                            'statistic_month_id' => $itemStat->id,
                                            'contract_id' => $moneyInfo->contract_id,
                                            'note' => $note
                                        ]);
                                    }
                                    $itemStat->current_paid = $paid;
                                    $itemStat->save();

                                }
                            }
                        } else {
                            $itemStats = StatisticMonth::query()->where('money_info_id', $moneyInfo->id)->get();
                            if($itemStats->count() > 0) {
                                foreach ($itemStats as $itemStat) {
                                    StatisticLog::query()->updateOrCreate([
                                        'collect_spend_id' => $item->id,
                                        'statistic_month_id' => $itemStat->id,
                                    ], [
                                        'amount' => $itemStat->amount,
                                        'month' => $itemStat->month,
                                        'year' => $itemStat->year,
                                        'type' => CollectSpend::COLLECT,
                                        'hostel_id' => $item->hostel_id,
                                        'room_id' => $item->room_id,
                                        'collect_spend_id' => $item->id,
                                        'contract_id' => $moneyInfo->contract_id,
                                        'statistic_month_id' => $itemStat->id,
                                        'note' => $note
                                    ]);
                                }
                            } else {
                                StatisticLog::query()->firstOrCreate([
                                    'collect_spend_id' => $item->id,
                                ], [
                                    'amount' => $item->amount,
                                    'month' => !empty($moneyInfo->date_action) ? $moneyInfo->date_action->month : Carbon::now()->month,
                                    'year' => !empty($moneyInfo->date_action) ? $moneyInfo->date_action->year : Carbon::now()->year,
                                    'type' => CollectSpend::COLLECT,
                                    'hostel_id' => $item->hostel_id,
                                    'room_id' => $item->room_id,
                                    'collect_spend_id' => $item->id,
                                    'contract_id' => $moneyInfo->contract_id,
                                    'note' => $note
                                ]);
                            }
                        }
                    } else {
                        $itemStat = StatisticMonth::create([
                            'month' => !empty($item->date_action) ? $item->date_action->month : Carbon::now()->month,
                            'year' => !empty($item->date_action) ? $item->date_action->year : Carbon::now()->year,
                            'amount' => $item->amount,
                            'contract_id' => $item->contract_id,
                            'room_id' => $item->room_id,
                            'hostel_id' => $item->hostel_id,
                            'money_info_id' => $item->money_info_id,

                        ]);
                        StatisticLog::query()->updateOrCreate([
                            'collect_spend_id' => $item->id,
                        ], [
                            'amount' => $item->amount,
                            'month' => !empty($item->date_action) ? $item->date_action->month : Carbon::now()->month,
                            'year' => !empty($item->date_action) ? $item->date_action->year : Carbon::now()->year,
                            'type' => CollectSpend::COLLECT,
                            'hostel_id' => $item->hostel_id,
                            'room_id' => $item->room_id,
                            'collect_spend_id' => $item->id,
                            'statistic_month_id' => $itemStat->id,
                            'contract_id' => $item->contract_id,
                            'note' => $note
                        ]);
                    }
                }
            } else {
                if ($item->is_deposit) {
                    $type = TypeSpend::query()
                        ->where('is_default', TypeSpend::TIEN_COC)
                        ->where('owner_id', $item->hostel->owner_id)
                        ->first();
                    if ($type) {
                        $item->type_purpose = $type->id;
                    }
                }
                if (!$item->is_deposit) {
                    StatisticLog::query()->updateOrCreate([
                        'collect_spend_id' => $item->id,
                    ], [
                        'amount' => $item->amount,
                        'month' => !empty($item->date_action) ? $item->date_action->month : Carbon::now()->month,
                        'year' => !empty($item->date_action) ? $item->date_action->year : Carbon::now()->year,
                        'type' => CollectSpend::SPEND,
                        'hostel_id' => $item->hostel_id,
                        'room_id' => $item->room_id,
                        'collect_spend_id' => $item->id,
                        'contract_id' => $item->contract_id,
                        'owner_id' => $item->owner_id,
                        'note' => $note
                    ]);
                }
            }


            if (empty($item->code)) {
                $code = Carbon::now()->format('dmY') . $item->id;
                $item->code = $code;
            }

            $item->hostel_name = $hostelName;
            $item->room_name = $roomName;
            $item->money_info_name = $moneyInfoName;
            $item->code = Carbon::now()->format('dmY') . $item->id;
            $item->contract_id = $contractId;
            $item->money_info_type = $moneyInfoType;
            if ($contract) {
                if ($item->is_deposit == false) {
                    if (empty($item->payer)) {
                        $item->payer = $contract->name;
                    }
                }
            }
            $item->save();

            if ($item->user) {
                $staff = $item->user;
                if ($staff->type == User::STAFF) {
                    $owner = $staff->owner;
                    if ($owner) {
                            \Notification::send($owner, new SendWhenStaffCollect($item->id));
                    }
                }
            }
        });

        static::deleted(function ($item) {
            StatisticLog::query()->where('collect_spend_id', $item->id)->delete();
            $moneyInfoId = $item->money_info_id;
            if(!empty($moneyInfoId))
            {
                StatisticMonth::query()->where('money_info_id', $moneyInfoId)->delete();
            }
            $reserveId = $item->reserve_id;
            if (!empty($reserveId)) {
                StatisticLog::query()
                    ->where('reserve_id', $reserveId)
                    ->delete();
            }
        });

        static::updated(function ($item) {
            $dateAction = $item->date_action;
            $check = StatisticLog::query()
                ->where('collect_spend_id', $item->id)
                ->count();

            if (!empty($dateAction)) {
                $month = $item->date_action->month;
                $year = $item->date_action->year;
                if($check == 1) {

                    StatisticLog::query()->where('collect_spend_id', $item->id)
                        ->doesntHave('statMonth')
                        ->doesntHave('moneyInfo')
                        ->update([
                            'month' => $month,
                            'year' => $year
                        ]);
                }
            }
            if($check == 1) {
                StatisticLog::where('collect_spend_id', $item->id)
                    ->update([
                        'amount' => $item->amount,
                    ]);
            }
        });
    }

    public function getPaymentMethodTextAttribute()
    {
        $type = $this->attributes['payment_method'];

        if ($type == CollectSpend::BANK) {
            return 'Chuyển khoản';
        }

        return 'Tiền mặt';
    }

    public function getTypeCpTextAttribute()
    {
        if (($this->attributes['type'] == CollectSpend::SPEND) && ($this->attributes['type_purpose'] != null)) {
            return optional($this->typespend)->name;
        }
        return optional($this->typeCollect)->name;

    }

    public function getTypeTextAttribute()
    {
        $type = $this->attributes['type'];

        if ($type == CollectSpend::COLLECT) {
            return '<label class="label label-success">Thu vào</label>';
        } else if ($type == CollectSpend::SPEND) {
            return '<label class="label label-danger">Chi ra</label>';
        }

        return '<label class="label label-primary">Chưa rõ trạng thái</label>';
    }

    public function files()
    {
        return $this->hasMany(CollectSpendFile::class);
    }

    public function hostel()
    {
        return $this->belongsTo('App\Models\Hostel');
    }

    public function room()
    {
        return $this->belongsTo('App\Models\Room');
    }

    public function user()
    {
        return $this->belongsTo(User::class)->withTrashed();
    }

    public function contract()
    {
        return $this->belongsTo(Contract::class);
    }

    public function transaction()
    {
        return $this->belongsTo(Transaction::class);
    }

    public function moneyInfo()
    {
        return $this->belongsTo(MoneyInfo::class);
    }

    public function typespend()
    {
        return $this->belongsTo(TypeSpend::class, 'type_purpose', 'id');
    }

    public function cycle()
    {
        return $this->hasOne(CollectSpendCycle::class, 'collect_spend_id', 'id');
    }

    public function typeCollect()
    {
        return $this->belongsTo(TypeCollect::class, 'type_collect_id', 'id');
    }

    public function getNoteTextAttribute()
    {
        $note = $this->attributes['note'];
        if (empty($note)) {
            return $note;
        }
        try {

            if (str_contains($note, 'Thanh toán tiền cọc giữ chỗ')) {
                //  return str_replace('')
                $contract = $this->contract;
                if ($contract) {
                    return 'Hoàn tiền cọc giữ chỗ để vào hợp đồng ' . $contract->code . ' (Chi tự động)';
                }
            }
        } catch (\Exception $exception) {
            return $note;
        }
        return $note;
    }

}
