<?php

namespace App\Models;

use App\Http\Helpers\ProfitCalculator;
use App\Notifications\ProposalAccepted;
use App\Notifications\RefundCreated;
use App\Traits\HasMilestones;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
use Overtrue\LaravelLike\Traits\Likeable;

class
Proposal extends Model
{
    use HasFactory;
    use HasMilestones;
    use SoftDeletes;
    use Likeable;

    protected $guarded = [];
    protected $appends = [
        'isLikedByUser'
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        "accepted" => "boolean",
    ];

    public function proposalable()
    {
        return $this->morphTo();
    }

    public function getIsLikedByUserAttribute(){
        return [
            'isLiked'=> Auth::user() != null && $this->isLikedBy(Auth::user()) && $this->deleted_at == null,
        ];
    }

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

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

    public function accept(string $clientSignature)
    {
        $this->milestones()->first()->pay($clientSignature);
    }

    public function createMilestones()
    {
        $duration = $this->duration;
        if ($this->project->rate_type == 'daily') {
            $months = 0;
            while ($this->duration >= 22) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => $this->amount * 22,
                        'duration' => 22,
                    ]
                );
                $months++;
                $this->duration -= 22;
            }
            if ($this->duration > 0) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => $this->amount * $this->duration,
                        'duration' => $this->duration,
                    ]
                );
            }
        } else if ($this->project->rate_type == 'monthly') {
            $months = 0;
            while ($this->duration >= 22) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => $this->amount,
                        'duration' => 22,
                    ]
                );
                $months++;
                $this->duration -= 22;
            }
            if ($this->duration > 0) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => ($this->amount )* $this->duration / 22,
                        'duration' => $this->duration,
                    ]
                );
            }
        } else if ($this->project->rate_type == 'yearly') {
            $months = 0;
            while ($this->duration >= 22) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => $this->amount / 12,
                        'duration' => 22,
                    ]
                );
                $months++;
                $this->duration -= 22;
            }
            if ($this->duration > 0) {
                $this->milestones()->create(
                    [
                        'name' => now()->addMonths($months)->monthName . ' for ' . $this->project->title,
                        'amount' => ($this->amount * $this->duration) / (22 * 12),
                        'duration' => $this->duration,
                    ]
                );
            }
        }
        //dd($duration,$this->duration);
        $this->duration = $duration;
        //dd($duration,$this->duration);
    }

    public function confirmPayment(array $data)
    {
        $this->update([
            'status' => "Accepted",
            "accepted" => true,
        ]);
        $this->save();
        $project = $this->project;
        $project->update([
            "projectable_id" => $this->proposalable_id,
            "projectable_type" => $this->proposalable_type,
            'amount' => $this->amount,
            "duration"=> $this->duration,
            "status"=>'Processing'
        ]);
        $project->save();

        $project->contract()->save(Contract::create([
            'project_id' => $project->id,
            'user_id' => $project->user_id,
            'contractor_id' => $this->proposalable_id,
            'contractor_type' => $this->proposalable_type,
            'client_signature' => $data['client_signature'],
            "user_signed_at" => now(),
            'amount' => $this->project->budget_type == "Rate" ? $this->calculateAmount() :$this->amount,
            'paid_amount' => $data['paid_amount'] ?? 0,
            'proposal_id' => $this->id,
        ]));

        $this->proposalable->notify(new ProposalAccepted($this));
        return $this;
    }

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

    public function decline()
    {
        $this->update([
            'status' => "Declined",
            "accepted" => false,
        ]);
        $this->save();
        return $this;
    }

    public function calculateAmount(){
        if ($this->project->rate_type == 'daily') {
            return $this->amount * $this->duration;
        } else if ($this->project->rate_type == 'monthly') {
            return ($this->amount/22)* ($this->duration);
        } else if ($this->project->rate_type == 'yearly') {
            return $this->amount * ($this->duration) /(22*12);
        }
    }

    public function refund(?bool $fromAdmin=false){
        $milestone = $this->milestones()->first();
        $this->project->status = 'Cancelled';
        $this->project->save();
        $this->project->contract->status = 'Canceled';
        $this->project->contract->save();
        $milestoneName = $milestone->name;
        $amount = $milestone->amount;
        if($fromAdmin){
            $this->proposalable->wallet->activities()
                ->create([
                    'amount' => ProfitCalculator::calculate($amount),
                    'activity_en' => ProfitCalculator::calculate($amount) .' has been refunded from your muhandisin wallet to source' ,
                    'activity_ar' => ProfitCalculator::calculate($amount).' تم ردهم الي المصدر من محفظة مهندسين  ',
                    'status' => 'refunded',
                ]);
        }else{
            $this->proposalable->wallet->activities()
                ->create(['amount' => ProfitCalculator::calculate($amount),
                    'activity_en' => ProfitCalculator::calculate($amount) . ' has been refunded from your muhandisin wallet to source due to decline for ' . $milestoneName,
                    'activity_ar' => ProfitCalculator::calculate($amount) . ' تم ردهم الي المصدر من محفظة مهندسين بسبب رفض  ' . $milestoneName,
                    'status' => 'refunded',
                ]);
        }
        $this->proposalable->wallet->upcoming_payments -= ProfitCalculator::calculate($amount);
        $this->proposalable->wallet->save();
        $this->proposalable->notify(new RefundCreated($milestone));
        return $this;
    }
}
