<?php

namespace App\Http\Controllers;

use App\Enums\UserRole;
use App\Enums\UserStatus;
use App\Http\Controllers\Concerns\ManagesPartnerUploads;
use App\Http\Requests\CoursewarePartnerRequest;
use App\Models\AuthorisedPartner;
use App\Models\CoursewareCategory;
use App\Models\CoursewarePartner;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class CoursewarePartnerController extends Controller
{
    use ManagesPartnerUploads;

    private const PROFILE_FIELDS = [
        'applicant_name', 'designation', 'building', 'street', 'city', 'state', 'postal_code',
        'country', 'email', 'phone', 'institute_name', 'official_building', 'official_street',
        'official_city', 'official_state', 'official_postal_code', 'official_country',
        'official_email', 'official_phone', 'website', 'second_contact_name',
        'second_contact_email', 'second_contact_phone', 'mobile', 'practical_lab_area',
        'theory_classroom_area', 'requirements',
    ];

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

        $query = CoursewarePartner::with('user', 'authorisedPartner', 'category');
        $user = auth()->user();

        if ($user->isAuthorisedPartner() && $user->authorisedPartner) {
            $query->where('authorised_partner_id', $user->authorisedPartner->id);
        }

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

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

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

        $authorisedPartners = $this->selectableAuthorisedPartners();
        $categories = $this->selectableCategories();
        $page_title = 'Add Courseware Partner';
        $page_description = 'Create a courseware partner account';

        return view('iqec.courseware-partners.create', compact('authorisedPartners', 'categories', 'page_title', 'page_description'));
    }

    public function store(CoursewarePartnerRequest $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::CoursewarePartner,
                'status' => UserStatus::Pending,
            ]);

            $data = $this->storePartnerUploads($request, $request->only(self::PROFILE_FIELDS));
            $data['user_id'] = $user->id;
            $data['courseware_category_id'] = $request->courseware_category_id;
            $data['authorised_partner_id'] = $actor->isAuthorisedPartner() && $actor->authorisedPartner
                ? $actor->authorisedPartner->id
                : $request->authorised_partner_id;
            $partner = CoursewarePartner::create($data);

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

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

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

        $coursewarePartner->load('user', 'authorisedPartner.user', 'superAdmins', 'category');
        $page_title = 'Courseware Partner Details';
        $page_description = $coursewarePartner->applicant_name;

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

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

        $authorisedPartners = $this->selectableAuthorisedPartners();
        $categories = $this->selectableCategories($coursewarePartner->courseware_category_id);
        $page_title = 'Edit Courseware Partner';
        $page_description = $coursewarePartner->applicant_name;

        return view('iqec.courseware-partners.edit', compact('coursewarePartner', 'authorisedPartners', 'categories', 'page_title', 'page_description'));
    }

    public function update(CoursewarePartnerRequest $request, CoursewarePartner $coursewarePartner): RedirectResponse
    {
        $this->authorize('update', $coursewarePartner);

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

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

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

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

        $coursewarePartner->user->delete();

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

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

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

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

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

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

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

    private function selectableAuthorisedPartners()
    {
        $user = auth()->user();
        $query = AuthorisedPartner::with('user')->orderBy('applicant_name');

        if ($user->isAuthorisedPartner() && $user->authorisedPartner) {
            $query->whereKey($user->authorisedPartner->id);
        }

        return $query->get();
    }

    private function selectableCategories(?int $selectedId = null)
    {
        return CoursewareCategory::query()
            ->where(function ($query) use ($selectedId) {
                $query->where('is_active', true);

                if ($selectedId) {
                    $query->orWhere('id', $selectedId);
                }
            })
            ->orderBy('sort_order')
            ->orderBy('name')
            ->get();
    }
}
