<?php

namespace App\Http\Controllers;

use App\Http\Requests\YearlyPlanRequest;
use App\Models\AcademicSession;
use App\Models\SchoolClass;
use App\Models\Section;
use App\Models\Subject;
use App\Models\YearlyPlan;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;

class YearlyPlanController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('permission:academics.view', only: ['index', 'show']),
            new Middleware('permission:academics.create', only: ['create', 'store']),
            new Middleware('permission:academics.update', only: ['edit', 'update']),
            new Middleware('permission:academics.delete', only: ['destroy']),
        ];
    }

    public function index(Request $request)
    {
        $filters = $request->only(['class_id', 'section_id', 'subject_id']);

        $plans = YearlyPlan::with(['schoolClass', 'section', 'subject'])
            ->when($filters['class_id'] ?? null, fn ($q, $v) => $q->where('class_id', $v))
            ->when($filters['section_id'] ?? null, fn ($q, $v) => $q->where('section_id', $v))
            ->when($filters['subject_id'] ?? null, fn ($q, $v) => $q->where('subject_id', $v))
            ->latest()->get();

        // PDF / Word export of the (filtered) plans.
        $export = $request->input('export');
        if (in_array($export, ['pdf', 'word'], true)) {
            // Embed images as base64 so they render in PDF/Word without a web request.
            $plans->each(function ($p) {
                $p->image_data = null;
                if ($p->image && \Illuminate\Support\Facades\Storage::disk('public')->exists($p->image)) {
                    $bytes = \Illuminate\Support\Facades\Storage::disk('public')->get($p->image);
                    $mime = \Illuminate\Support\Facades\Storage::disk('public')->mimeType($p->image) ?: 'image/png';
                    $p->image_data = 'data:'.$mime.';base64,'.base64_encode($bytes);
                }
            });

            if ($export === 'pdf') {
                return \Barryvdh\DomPDF\Facade\Pdf::loadView('yearly-plans.export-pdf', ['plans' => $plans])
                    ->setPaper('a4', 'portrait')->download('yearly-planner.pdf');
            }

            // Word (.doc) — HTML document Microsoft Word opens natively.
            $html = view('yearly-plans.export-word', ['plans' => $plans])->render();

            return response($html, 200, [
                'Content-Type' => 'application/vnd.ms-word; charset=utf-8',
                'Content-Disposition' => 'attachment; filename="yearly-planner.doc"',
            ]);
        }

        return view('yearly-plans.index', array_merge($this->formData(), [
            'plans' => $plans,
            'filters' => $filters,
        ]));
    }

    public function create(): View
    {
        return view('yearly-plans.create', array_merge($this->formData(), [
            'plan' => new YearlyPlan,
        ]));
    }

    public function store(YearlyPlanRequest $request): RedirectResponse
    {
        $data = $request->validated();
        $data['image'] = $this->storeImage($request);

        $plan = YearlyPlan::create($data);

        return redirect()->route('yearly-plans.show', $plan)->with('success', 'Yearly plan added.');
    }

    public function show(YearlyPlan $yearlyPlan): View
    {
        $yearlyPlan->load(['schoolClass', 'section', 'subject', 'academicSession', 'creator']);

        return view('yearly-plans.show', ['plan' => $yearlyPlan]);
    }

    public function edit(YearlyPlan $yearlyPlan): View
    {
        return view('yearly-plans.edit', array_merge($this->formData(), [
            'plan' => $yearlyPlan,
        ]));
    }

    public function update(YearlyPlanRequest $request, YearlyPlan $yearlyPlan): RedirectResponse
    {
        $data = $request->validated();
        if ($request->hasFile('image')) {
            $this->deleteImage($yearlyPlan->image);
            $data['image'] = $this->storeImage($request);
        } else {
            unset($data['image']);
        }

        $yearlyPlan->update($data);

        return redirect()->route('yearly-plans.show', $yearlyPlan)->with('success', 'Yearly plan updated.');
    }

    public function destroy(YearlyPlan $yearlyPlan): RedirectResponse
    {
        $this->deleteImage($yearlyPlan->image);
        $yearlyPlan->delete();

        return redirect()->route('yearly-plans.index')->with('success', 'Yearly plan removed.');
    }

    private function formData(): array
    {
        return [
            'classes' => SchoolClass::active()->orderBy('level')->get(),
            'sections' => Section::active()->get(['id', 'class_id', 'name']),
            'subjects' => Subject::where('is_active', true)->orderBy('name')->get(),
            'sessions' => AcademicSession::orderByDesc('id')->get(),
        ];
    }

    private function storeImage(Request $request): ?string
    {
        if (! $request->hasFile('image')) {
            return null;
        }
        $branchId = app(\App\Support\BranchContext::class)->currentId()
            ?? auth()->user()?->branch_id
            ?? \App\Models\Branch::min('id');

        return $request->file('image')->store("branches/{$branchId}/yearly-plans", 'public');
    }

    private function deleteImage(?string $path): void
    {
        if ($path && Storage::disk('public')->exists($path)) {
            Storage::disk('public')->delete($path);
        }
    }
}
