<?php

namespace App\Http\Controllers;

use App\Enums\UserRole;
use App\Enums\UserStatus;
use App\Http\Controllers\Concerns\ManagesPartnerUploads;
use App\Http\Requests\AuthorisedPartnerRequest;
use App\Models\AuthorisedPartner;
use App\Models\Promoter;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class AuthorisedPartnerController extends Controller
{
    use ManagesPartnerUploads;

    private const PROFILE_FIELDS = [
        'applicant_name', 'designation', 'building', 'street', 'city', 'state', 'postal_code',
        'country', 'email', 'phone', 'institute_name', 'firm_type', 'official_building',
        'official_street', 'official_city', 'official_state', 'official_postal_code',
        'official_country', 'official_email', 'official_phone', 'operational_area',
        'experience', 'second_contact_name', 'second_contact_email', 'second_contact_phone',
    ];

    public function index(): View
    {
        $this->authorize('viewAny', AuthorisedPartner::class);

        $query = AuthorisedPartner::with('user', 'promoter')->withCount('coursewarePartners');
        $user = auth()->user();

        if ($user->isPromoter() && $user->promoter) {
            $query->where('promoter_id', $user->promoter->id);
        }

        $partners = $query->latest()->paginate(15);
        $page_title = 'Authorised Partners';
        $page_description = 'Manage authorised partners';

        return view('iqec.authorised-partners.index', compact('partners', 'page_title', 'page_description'));
    }

    public function create(): View
    {
        $this->authorize('create', AuthorisedPartner::class);

        $promoters = Promoter::with('user')->orderBy('applicant_name')->get();
        $page_title = 'Add Authorised Partner';
        $page_description = 'Create an authorised partner account';

        return view('iqec.authorised-partners.create', compact('promoters', 'page_title', 'page_description'));
    }

    public function store(AuthorisedPartnerRequest $request): RedirectResponse
    {
        DB::transaction(function () use ($request) {
            $actor = $request->user();

            $user = User::create([
                'name' => $request->applicant_name,
                'email' => $request->email,
                'password' => $request->password,
                'role' => UserRole::AuthorisedPartner,
                'status' => UserStatus::Pending,
            ]);

            $data = $this->storePartnerUploads($request, $request->only(self::PROFILE_FIELDS));
            $data['user_id'] = $user->id;
            $data['promoter_id'] = $actor->isPromoter() && $actor->promoter
                ? $actor->promoter->id
                : $request->promoter_id;
            $partner = AuthorisedPartner::create($data);

            if ($actor->isSuperAdmin()) {
                $partner->superAdmins()->attach($actor->id);
            }
        });

        return redirect()->route('authorised-partners.index')->with('success', 'Authorised partner created and is pending approval.');
    }

    public function show(AuthorisedPartner $authorisedPartner): View
    {
        $this->authorize('view', $authorisedPartner);

        $authorisedPartner->load('user', 'promoter.user', 'superAdmins', 'coursewarePartners.user');
        $page_title = 'Authorised Partner Details';
        $page_description = $authorisedPartner->applicant_name;

        return view('iqec.authorised-partners.show', compact('authorisedPartner', 'page_title', 'page_description'));
    }

    public function coursewarePartners(Request $request, AuthorisedPartner $authorisedPartner): View
    {
        $this->authorize('view', $authorisedPartner);
        abort_unless($request->ajax(), 404);

        $partners = $authorisedPartner->coursewarePartners()
            ->with('user')
            ->latest()
            ->paginate(10);

        return view('iqec.authorised-partners.partials.courseware-partners-list', compact('authorisedPartner', 'partners'));
    }

    public function edit(AuthorisedPartner $authorisedPartner): View
    {
        $this->authorize('update', $authorisedPartner);

        $promoters = Promoter::with('user')->orderBy('applicant_name')->get();
        $page_title = 'Edit Authorised Partner';
        $page_description = $authorisedPartner->applicant_name;

        return view('iqec.authorised-partners.edit', compact('authorisedPartner', 'promoters', 'page_title', 'page_description'));
    }

    public function update(AuthorisedPartnerRequest $request, AuthorisedPartner $authorisedPartner): RedirectResponse
    {
        $this->authorize('update', $authorisedPartner);

        DB::transaction(function () use ($request, $authorisedPartner) {
            $actor = $request->user();
            $userData = [
                'name' => $request->applicant_name,
                'email' => $request->email,
            ];
            if ($request->filled('password')) {
                $userData['password'] = $request->password;
            }
            $authorisedPartner->user->update($userData);

            $data = $this->storePartnerUploads(
                $request,
                $request->only(self::PROFILE_FIELDS),
                $authorisedPartner->photo_path,
                $authorisedPartner->id_proof_path
            );
            if ($actor->isPromoter() && $actor->promoter) {
                $data['promoter_id'] = $actor->promoter->id;
            } elseif ($actor->isSuperAdmin()) {
                $data['promoter_id'] = $request->promoter_id;
            }
            $authorisedPartner->update($data);
        });

        return redirect()->route('authorised-partners.index')->with('success', 'Authorised partner updated.');
    }

    public function destroy(AuthorisedPartner $authorisedPartner): RedirectResponse
    {
        $this->authorize('delete', $authorisedPartner);

        $authorisedPartner->user->delete();

        return redirect()->route('authorised-partners.index')->with('success', 'Authorised partner deleted.');
    }

    public function approve(AuthorisedPartner $authorisedPartner): RedirectResponse
    {
        $this->authorize('approve', $authorisedPartner);

        $authorisedPartner->user->update(['status' => UserStatus::Approved]);

        return back()->with('success', 'Authorised partner approved. They can now log in.');
    }

    public function reject(AuthorisedPartner $authorisedPartner): RedirectResponse
    {
        $this->authorize('approve', $authorisedPartner);

        $authorisedPartner->user->update(['status' => UserStatus::Rejected]);

        return back()->with('success', 'Authorised partner rejected.');
    }
}
