<?php

namespace Modules\Announcement\Http\Controllers;

use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\Request;
use Modules\Announcement\Entities\Announcement;
use Modules\Announcement\Http\Requests\AnnouncementRequest;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Announcement\Entities\Device;
use Modules\Announcement\Exports\AnnouncementsExport;

class AdminController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Announcement::class, 'announcement');
    }

    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $data = Announcement::query()
                ->filters($request);

            return Announcement::makeDataTable($data);
        }

        return view('announcement::admin.index');
    }

    public function trashed(Request $request)
    {
        $this->authorize('restore', Announcement::class);

        if ($request->ajax()) {
            $data = Announcement::query()
                ->onlyTrashed();

            return Announcement::makeDataTable($data, trash: true);
        }

        return view('announcement::admin.trashed');
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        return view('announcement::admin.create', ['announcement' => new Announcement()]);
    }

    /**
     * Store a newly created announcement in storage
     *
     * @param  \Modules\Announcement\Http\Requests\AnnouncementRequest $request
     * @param  \Modules\Announcement\Entities\Announcement $announcement
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(AnnouncementRequest $request, Announcement $announcement)
    {
        $announcement->create(array_merge($request->validated(), [
            'is_active' => $request->boolean('is_active'),
        ]));

        return redirect()->route('announcement.index')->withStatus(__('New announcement successfully created.'));
    }

    /**
     * Show the form for editing the specified announcement
     *
     * @param  \Modules\Announcement\Entities\Announcement $announcement
     * @return \Illuminate\View\View
     */
    public function edit(Announcement $announcement)
    {
        return view('announcement::admin.edit', ['announcement' => $announcement]);
    }

    public function notify(Announcement $announcement)
    {
        $redirect = redirect()->route('announcement.edit', $announcement);

        try {
            throw_unless($announcement->is_active, __('Announcement is not in status active to send notification.'));

            Device::notifyViaMulticast($announcement->title, $announcement->message, throw: true);

            return $redirect->withStatus(__("Announcement #$announcement->id successfully sent notification."));
        } catch (Exception $e) {
            return $redirect->withErrors($e->getMessage());
        }
    }

    /**
     * Update the specified announcement in storage
     *
     * @param  \Modules\Announcement\Http\Requests\AnnouncementRequest $request
     * @param  \Modules\Announcement\Entities\Announcement $announcement
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(AnnouncementRequest $request, Announcement $announcement)
    {
        $announcement->update(array_merge($request->validated(), [
            'is_active' => $request->boolean('is_active'),
        ]));

        return redirect()->route('announcement.edit', $announcement)->withStatus(__("Announcement #$announcement->id successfully updated."));
    }

    /**
     * Remove the specified announcement from storage
     *
     * @param  \Modules\Announcement\Entities\Announcement $announcement
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(Announcement $announcement)
    {
        $announcement->delete();

        return redirect()->route('announcement.index')->withStatus(__("Announcement #$announcement->id successfully deleted."));
    }

    public function restore($id)
    {
        $announcement = Announcement::onlyTrashed()->findOrFail($id);

        $this->authorize('restore', $announcement);

        if ($announcement->trashed()) {
            $announcement->restore();

            return redirect()->route('announcement.trashed')->withStatus(__("Announcement #$announcement->id successfully restored."));
        }

        return redirect()->route('announcement.trashed')->withErrors(__("Announcement #$announcement->id cannot be restored."));
    }

    public function export(Request $request)
    {
        $this->authorize('export', Announcement::class);

        return Excel::download(new AnnouncementsExport($request), 'announcements-' . now()->format('dmY_His') . '.xlsx');
    }
}
