<?php

namespace App\Http\Controllers;

use Illuminate\Support\Arr;
use App\Services\MemberService;
use App\Services\RevisionService;
use App\Http\Resources\MemberResource;
use App\Http\Requests\Member\MemberStore;
use App\Http\Requests\Member\RevisionStore;
use App\Repositories\Member;
use App\Repositories\User;
use App\Services\QueryBuilderService;
use Illuminate\Http\Request;

class MemberController extends Controller
{

    private MemberService $memberService;
    private RevisionService $revisionService;
    private QueryBuilderService $queryBuilderService;

    public function __construct(
        MemberService $memberService,
        RevisionService $revisionService,
        QueryBuilderService $queryBuilderService
    ) {
        $this->memberService = $memberService;
        $this->revisionService = $revisionService;
        $this->queryBuilderService = $queryBuilderService;

        $this->middleware('auth:sanctum', ['except' => ['storeMemberRevisions']]);
    }

    public function index(Request $request)
    {
        $members = $this->queryBuilderService
            ->createQueryBuilder(Member::class, Member::class, $request)
            ->with([
                'addresses',
                'contacts',
                'main_branch',
                'management_links',
                'revision',
                'sub_branches',
                'summaries',
                'contributions',
                'users',
            ])
            ->withTrashed()
            ->defaultSort('-id')
            ->get();

        return response()->json(MemberResource::collection($members), 201);
    }

    public function store(MemberStore $request)
    {
        /** @var User */
        $user = auth()->user();
        $isSuperAdmin = $user->hasRole('super_admin');
        $isAdmin = $user->hasRole('admin');
        // $isOperator = $user->hasRole('operator');
        // $isAdminOrOperator = $isAdmin || $isOperator;
        // $isUserDelegated = $member->user_id === $user->id;


        if (!$isSuperAdmin && !$isAdmin) {
            return response()->json(['message' => 'You have no rights to do this'], 401);
        }

        $hasLogo = isset($request['logo']) && $request->hasFile('logo');

        $request_data = Arr::except($request->validated(), ['sub_branches']);

        if (!isset($request_data['user_id']) || !is_int($request_data['user_id'])) {
            $request_data['user_id'] = $user->id;
        }

        $member = $this->memberService->save($request_data);

        if ($request->revisor_id && $request->revisor_id == $user->id) {
            $member->revision->revisor_id = $user->id;
            $member->revision->touch();
            $member->revision->accepted_at = $member->revision->updated_at;
            $member->revision->timestamps = false;
            $member->revision->save();
        }

        $sub_branches = json_decode(html_entity_decode(stripslashes($request['sub_branches'])));

        $member->sub_branches()->sync($sub_branches);

        if ($hasLogo) $member->addMediaFromRequest('logo')->toMediaCollection('members_logos');

        // Emit Event to update members
        broadcast(new \App\Events\MembersUpdated);

        return response()->json($member, 201);
    }

    public function storeMemberRevision(RevisionStore $request)
    {
        if ($request->user_id != auth()->user()->id) {
            return response()->json(['message' => 'You have no rights to do this'], 401);
        }

        $member = $this->memberService->get($request->member_id);

        if (!$member) {
            return response()->json(['message' => 'Member not found.'], 404);
        }

        if ($member->user_id != auth()->user()->id) {
            return response()->json(['message' => 'You have no rights to do this'], 401);
        }

        $hasLogo = isset($request['logo']) && $request->hasFile('logo');
        $revision = $this->revisionService->save($request->validated());

        if ($hasLogo) $member->addMediaFromRequest('logo')->toMediaCollection('members_logos');

        // Emit Event to update members
        broadcast(new \App\Events\MembersUpdated);

        return response()->json($revision, 201);
    }

    public function show($id)
    {
        $member = $this->memberService->getOneWith($id, ['summaries', 'addresses', 'contacts', 'contributions', 'sub_branches', 'revision', 'management_links']);

        return response()->json(new MemberResource($member));
    }

    public function destroy(String $id, $forceDelete = false)
    {
        $isSuperAdmin = auth()->user()->hasRole('super_admin');
        $isAdmin = auth()->user()->hasRole('admin');
        $isSuperAdminOrAdmin = $isSuperAdmin || $isAdmin;

        if (!$isSuperAdminOrAdmin) {
            return response()->json(['message' => 'You have no rights to do this'], 401);
        }

        $this->memberService->delete($id, $forceDelete);
        return response()->json(null, 204);
    }

    public function countAll()
    {
        return response()->json($this->memberService->countAll());
    }
}
