<?php

namespace App\Http\Controllers;

use App\Http\Helpers\FileUploader;
use App\Models\Project;
use App\Models\Proposal;
use App\Models\ProposalFile;
use App\Notifications\ProposalAdded;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class ProposalController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        //
    }

    public function store(Request $request)
    {
        try {
            $transaction = DB::transaction(function () use ($request) {
                $data = $this->validateRequest($request);
                if ($request->engineer) {
                    $data["proposalable_id"] = Auth::user()->engineer->id;
                    $data["proposalable_type"] = "App\Models\Engineer";
                } else {
                    $data["proposalable_id"] = Auth::user()->firm->id;
                    $data["proposalable_type"] = "App\Models\Firm";
                }

                $proposal = Proposal::create($data);
                if ($proposal->project->budget_type == "Rate") {
                    $proposal->createMilestones();
                }

                else if ($data['per_project']) {
                    $proposal->addMilestone([
                        "name" => $proposal->project->title,
                        "amount" => $proposal->amount,
                        "duration" => $proposal->duration,
                        "deliverables" => $request->deliverables,
                    ]);
                } else {
                    foreach ($request->milestones as $milestone) {
                        $proposal->addMilestone($milestone);
                    }
                }
                if ($request->hasFile('files')) {
                    foreach ($request->file('files') as $file) {
                        ProposalFile::create([
                            'proposal_id' => $proposal->id,
                            'url' => FileUploader::store('deliverables/', $file),
                            'type' => FileUploader::getFileType($file),
                        ]);
                    }
                }
                $proposal->save();
                $proposal->project->user->notify(new ProposalAdded($proposal));
            });
            $slug = Project::find($request->project_id)->slug;
            return is_null($transaction) ? redirect()->route('project.show', ['slug' => $slug])->with(['success' => 'success']) : $transaction;
        } catch (Exception $exception) {
            return back(303)->with(['error' => $exception->getMessage()]);
        }
    }

    public function save(Proposal $proposal){
        Auth::user()?->toggleLike($proposal);
        return back(303)->with(["success" => "success"]);
    }
    public function validateRequest(Request $request, ?bool $update = false)
    {
        if ($update) {
            $request->validate([
                'files' => 'array',
                'engineer' => 'bool'
            ]);
        }
        return $request->validate([
            'cover_letter' => $update ? 'required' : 'nullable',
            'description' => $update ? 'required' : 'nullable',
            'amount' => $update ? 'required|double' : 'nullable',
            'duration' => $update ? 'required|int' : 'nullable',
            'project_id' => $update ? 'required' : 'nullable',
            'per_project' => $update ? 'required' : 'nullable',
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        return view('create-proposal');
    }

    /**
     * Display the specified resource.
     *
     * @param Proposal $proposal
     * @return Response
     */
    public function show(Proposal $proposal)
    {

        $proposal->load([
            "proposalable" => [
                'user',
                'location'
            ],
            "files",
            'contract',
            'milestones' => [
                'deliverables',
                'files',
            ],
            'project.user.wallet'
        ]);


        return Inertia::render("Projects/Client/Proposals/Single/Index", [
            "proposal" => $proposal,
            "worker" => false,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param Proposal $proposal
     * @return Response
     */
    public function edit(Proposal $proposal)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param Proposal $proposal
     * @return Response
     */
    public function update(Request $request)
    {
        $proposal = Proposal::find($request->id);
        try {
            $transaction = DB::transaction(function () use ($request, $proposal) {
                $data = $this->validateRequest($request, true);

                $proposal->update($data);
                if ($request->has('duration') && $proposal->project->budget_type == "Rate"){
                    foreach ($proposal->milestones as $milestone){
                        $milestone->delete();
                    }
                    $proposal->createMilestones();
                }else if($request->has('milestones')){
                    foreach ($proposal->milestones as $milestone){
                        $milestone->delete();
                    }
                    foreach ($request->milestones as $milestone) {
                        $proposal->addMilestone($milestone);
                    }
                }
                foreach ($proposal->files()->get() as $item) {
                    if (!in_array($item->id, array_column($request->input('files'), 'id'))) {
                        $item->delete();
                    }
                }
                if (count($request->file('files')) > 0) {
                    foreach ($request->file('files') as $item) {
                        ProposalFile::create([
                            'proposal_id' => $proposal->id,
                            'url' => FileUploader::store('proposalsFiles/', $item),
                        ]);
                    }
                }
                $proposal->save();
                $proposal->project->user->notify(new ProposalAdded($proposal));
            });
            return is_null($transaction) ? back(303)->with(['success' => 'success']) : $transaction;
        } catch (Exception $exception) {
            return back(303)->with(['error' => $exception->getMessage()]);
        }
    }

    public function destroy(Request $request)
    {
        $proposal = Proposal::find($request->id);
        $proposal->delete();
        return back(303)->with(['success' => 'success']);
    }
}
