<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Broadcast;
use App\Models\Customer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\Rule;
use RealRashid\SweetAlert\Facades\Alert;
use Yajra\DataTables\Facades\DataTables;

class BroadcastController extends Controller
{
    public function source(Request $request)
    {
        Gate::authorize('read broadcasts');

        if (!in_array($request->tipe, array_keys(Broadcast::TIPE_LABEL))) {
            abort(404);
        }

        $datatables = $request->tipe === Broadcast::TIPE_DINI ? $this->sourcePeringatanDini($request) : $this->sourceKejadianBencana($request);

        return $datatables
            ->filter(function ($query) {
                if ($search = request()->input('search.value')) {
                    $query->having('searchable', 'like', "%" . $search . "%");
                }
            })
            ->addIndexColumn()
            ->addColumn('action', 'admin.broadcasts.index-actions')
            ->toJson();
    }

    protected function sourcePeringatanDini(Request $request): \Yajra\DataTables\EloquentDataTable
    {
        $user = $request->user();

        /**
         * @var \Illuminate\Database\Query\Builder $query
         */
        $query = Broadcast::query()
            ->with('creator')
            ->selectRaw('broadcasts.*')
            ->selectRaw('CONCAT_WS(" ", broadcasts.judul, broadcasts.pesan) as `searchable`')
            ->where('tipe', 'peringatan_dini');

        if ($user->hasRole('superadmin')) {
            $query->withTrashed();
        }

        $order = $request->order;
        if (is_array($order) && count($order)) {
            $sortBy = $order[0]['column'] ?? null;
            $sort = $order[0]['dir'] ?? null;

            if ($sortBy == 1) {
                $query->orderBy('broadcasts.judul', $sort == 'asc' ? 'asc' : 'desc');
            } elseif ($sortBy == 2) {
                $query->orderByRaw('CONVERT(DATE, broadcasts.tanggal), broadcasts.tanggal', $sort == 'asc' ? 'asc' : 'desc');
            } elseif ($sortBy == 3) {
                $query->orderBy('broadcasts.tanggal', $sort == 'asc' ? 'asc' : 'desc');
            } else {
                $query->orderByDesc('broadcasts.tanggal');
            }
        }

        return DataTables::eloquent($query)
            ->editColumn('tanggal', function($item) {
                return !$item->tanggal ? '-' : $item->tanggal->format('j M Y H:i');
            })
            ->addColumn('creator', function($item) {
                return !$item->creator ? '-' : $item->creator->name;
            })
            ->rawColumns(['action']);
    }

    protected function sourceKejadianBencana(Request $request): \Yajra\DataTables\EloquentDataTable
    {
        $user = $request->user();

        /**
         * @var \Illuminate\Database\Query\Builder $query
         */
        $query = Broadcast::query()
            ->selectRaw('broadcasts.*')
            ->selectRaw('bencanas.nama as bencana')
            ->selectRaw('CONCAT_WS(" ", broadcasts.kronologi, bencanas.nama) as `searchable`')
            ->leftJoin('bencanas', 'bencanas.id', '=', 'broadcasts.bencana_id')
            ->where('tipe', 'kejadian_bencana');

        if ($user->hasRole('superadmin')) {
            $query->withTrashed();
        }

        if ($request->bencana_id) {
            $query->where('bencana_id', $request->bencana_id);
        }

        $order = $request->order;
        if (is_array($order) && count($order)) {
            $sortBy = $order[0]['column'] ?? null;
            $sort = $order[0]['dir'] ?? null;

            if ($sortBy == 1) {
                $query->orderBy('bencanas.nama', $sort == 'asc' ? 'asc' : 'desc');
            } else {
                $query->orderByDesc('broadcasts.created_at');
            }
        }

        return DataTables::eloquent($query)
            ->addColumn('action', 'admin.broadcasts.index-actions')
            ->rawColumns(['action']);
    }

    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        Gate::authorize('read broadcasts');

        $tipeLabel = collect(Broadcast::TIPE_LABEL);

        return view('admin.broadcasts.index', compact('tipeLabel'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        Gate::authorize('create broadcasts');

        return view('admin.broadcasts.create');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        Gate::authorize('create broadcasts');

        if ($request->tipe !== Broadcast::TIPE_DINI) {
            return abort(404);
        }

        $request->validate([
            'judul' => 'required|string',
            'pesan' => 'required|string',
            'tipe' => [
                'required',
                Rule::in(array_keys(Broadcast::TIPE_LABEL))
            ],
        ]);

        $user = $request->user();

        DB::beginTransaction();

        try {
            $broadcast = new Broadcast();

            $broadcast->forceFill([
                'judul' => $request->judul,
                'pesan' => $request->pesan,
                'tipe' => $request->tipe,
                'tanggal' => now(),
                'created_by' => $user->id,
            ])->save();

            if ($broadcast->tipe === Broadcast::TIPE_DINI) {
                $fcm_auth_key = env('FIREBASE_AUTH_KEY');

                $response = Http::withHeaders([
                    'Content-type' => 'application/json',
                    'Authorization' => 'key='.$fcm_auth_key,
                ])->post('https://fcm.googleapis.com/fcm/send', [
                    'notification' => [
                        'title' => $broadcast->judul,
                        'body' => $broadcast->pesan,
                        'icon' => asset('assets/images/icons/bpbdmini.png'),
                        'click_action' => "",
                    ],
                    'registration_ids' => Customer::whereNotNull('token')->get()->pluck('token')->toArray(),
                ]);

                if (!$response->successful()) {
                    \Log::info("Broadcast FCM: Response Error", [
                        'broadcast' => $broadcast,
                        'successful' => $response->successful(),
                        'json' => $response->json(),
                    ]);
                }
            }

            DB::commit();

            Alert::success('Success', 'Broadcast berhasil dikirim');

            return redirect()->route('admin.broadcast.index');
        } catch (\Exception $e) {
            DB::rollback();

            return redirect()->back()->with('error-message', $e->getMessage())->withInput();
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(Broadcast $broadcast)
    {
        Gate::authorize('denied');

        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Broadcast $broadcast)
    {
        Gate::authorize('denied');

        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Broadcast $broadcast)
    {
        Gate::authorize('denied');

        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Request $request, $id)
    {
        Gate::authorize('delete broadcasts');

        $query = Broadcast::query();

        if ($isSuperadmin = $request->user()->hasRole('superadmin')) {
            $query->withTrashed();
        }

        $broadcast = $query->findOrFail($id);

        if ($request->restore == '1' && $isSuperadmin) {
            $broadcast->forceFill([ 'deleted_at' => null ])->save();
        } else {
            $broadcast->delete();
        }

        if ($request->ajax()) {
            return response()->json(['success' => true]);
        }

        Alert::success('Success', 'Sarana prasarana berhasil di hapus');

        return redirect()->route('admin.sarpras.index');
    }
}