<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Tema;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use App\Notifications\NotifikasiAudit;
use Illuminate\Support\Str;
use Carbon\Carbon;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;

class NotifikasiController extends Controller
{
    private function compressImage($imageFile, $path, $maxKb = 256)
    {
        $manager = new ImageManager(new Driver());
        $img = $manager->read($imageFile);

        $width = 1200;
        $quality = 85;

        do {
            $resized = clone $img;
            $resized->scaleDown(width: $width);

            $tempPath = storage_path('app/temp_img.jpg');
            $resized->toJpeg($quality)->save($tempPath);

            $sizeKb = filesize($tempPath) / 1024;

            if ($sizeKb > $maxKb) {
                if ($quality > 10) {
                    $quality -= 5;
                } else {
                    $width -= 100;
                    $quality = 85;
                }
            }
        } while ($sizeKb > $maxKb && $width > 300);

        $resized->toJpeg($quality)->save(public_path('storage/' . $path));
    }

    public function index()
    {
        $notifikasi = auth()->user()->notifications()
            ->where('type', NotifikasiAudit::class)
            ->latest()
            ->get();

        $temaList = Tema::whereHas('periode', function ($q) {
            $q->where('status', 1);
        })->orderBy('nama')->get();

        return view('admin.notifikasi', compact('notifikasi', 'temaList'));
    }

    public function kirim(Request $request)
    {
        $request->validate([
            'mode'             => 'required|in:umum,semua,beberapa',
            'emails'           => 'nullable|array|max:3',
            'emails.*'         => 'nullable|email',
            'selected_subject' => 'required|string|in:audit,verifikasi',
            'tema'             => 'nullable|string|max:255',
            'tanggal'          => 'nullable|date',
            'isi_pesan'        => 'required|string',
            'foto'             => 'nullable|image|mimes:jpeg,jpg,png',
        ]);

        $judul = $this->getJudul($request->selected_subject);

        $tanggalFormatted = $request->filled('tanggal')
            ? Carbon::parse($request->tanggal)->translatedFormat('d F Y')
            : null;

        $fotoPath = null;

        if ($request->hasFile('foto')) {
            $foto = $request->file('foto');
            $ext = 'jpg';
            $slug = Str::slug($judul);
            $namaFile = $slug . '-' . time() . '.' . $ext;
            $path = 'notifikasi/' . $namaFile;

            $this->compressImage($foto, $path, 256);
            $fotoPath = $path;
        }

        $penerima = [];
        $users = collect();
        $emailGagal = false;
        $groupId = (string) Str::uuid();

        $dataNotifikasi = [
            'group_id'  => $groupId,
            'judul'     => $judul,
            'tema'      => $request->tema,
            'tanggal'   => $tanggalFormatted,
            'isi_pesan' => $request->isi_pesan,
            'foto'      => $fotoPath,
            'sender_id' => auth()->id(),
            'penerima'  => [],
        ];

        if ($request->mode === 'umum') {
            $emailUmum = 'info@padma.co.id';

            $penerima[] = [
                'id'       => null,
                'name'     => 'Umum',
                'division' => '-',
                'email'    => $emailUmum,
            ];

            $dataNotifikasi['penerima'] = $penerima;

            try {
                Mail::raw($request->isi_pesan, function ($message) use ($emailUmum, $judul) {
                    $message->to($emailUmum)
                        ->subject($judul);
                });
            } catch (\Throwable $e) {
                $emailGagal = true;
                Log::error('Gagal mengirim email umum: ' . $e->getMessage());
            }

        } elseif ($request->mode === 'semua') {
            $users = User::all();

            if ($users->isEmpty()) {
                return back()->with('error', 'Tidak ada auditor yang tersedia untuk dikirimi notifikasi.');
            }

            $penerima = $users->map(function ($u) {
                return [
                    'id'       => $u->id,
                    'name'     => $u->name,
                    'division' => $u->bagian->nama_bagian ?? '-',
                    'email'    => $u->email,
                ];
            })->toArray();

            $dataNotifikasi['penerima'] = $penerima;

            Notification::sendNow($users, new NotifikasiAudit($dataNotifikasi), ['database']);

            try {
                Notification::sendNow($users, new NotifikasiAudit($dataNotifikasi), ['mail']);
            } catch (\Throwable $e) {
                $emailGagal = true;
                Log::error('Gagal mengirim email semua auditor: ' . $e->getMessage());
            }

        } elseif ($request->mode === 'beberapa') {
            $emails = array_filter($request->emails ?? []);

            if (empty($emails)) {
                return back()->with('error', 'Masukkan minimal satu email auditor.');
            }

            $users = User::whereIn('email', $emails)->get();

            if ($users->isEmpty()) {
                return back()->with('error', 'Tidak ada user valid untuk dikirimi notifikasi.');
            }

            $penerima = $users->map(function ($u) {
                return [
                    'id'       => $u->id,
                    'name'     => $u->name,
                    'division' => $u->bagian->nama_bagian ?? '-',
                    'email'    => $u->email,
                ];
            })->toArray();

            $dataNotifikasi['penerima'] = $penerima;

            Notification::sendNow($users, new NotifikasiAudit($dataNotifikasi), ['database']);

            try {
                Notification::sendNow($users, new NotifikasiAudit($dataNotifikasi), ['mail']);
            } catch (\Throwable $e) {
                $emailGagal = true;
                Log::error('Gagal mengirim email auditor tertentu: ' . $e->getMessage());
            }
        }

        Notification::sendNow(auth()->user(), new NotifikasiAudit($dataNotifikasi), ['database']);

        if ($emailGagal) {
            return back()->with(
                'warning',
                'Notifikasi berhasil disimpan, tetapi email gagal dikirim. Periksa konfigurasi SMTP atau alamat email penerima.'
            );
        }

        return back()->with('success', 'Notifikasi berhasil dikirim.');
    }

    public function lihat($id)
{
    $notif = auth()->user()->notifications()->findOrFail($id);

    $data = $notif->data ?? [];

    if (!isset($data['penerima'])) {
        $data['penerima'] = [];
    }

    $groupId  = $data['group_id'] ?? null;
    $judul    = $data['judul'] ?? null;
    $isiPesan = $data['isi_pesan'] ?? null;
    $senderId = $data['sender_id'] ?? auth()->id();

    $penerima = collect($data['penerima'])->map(function ($user) use ($groupId, $judul, $isiPesan, $senderId) {
        $userId = $user['id'] ?? null;

        if (!$userId) {
            return array_merge($user, [
                'read_at'     => null,
                'status_baca' => 'Terkirim Email',
            ]);
        }

        $auditor = User::find($userId);

        if (!$auditor) {
            return array_merge($user, [
                'read_at'     => null,
                'status_baca' => 'Belum Dibaca',
            ]);
        }

        if ($groupId) {
            $notifUser = $auditor->notifications()
                ->where('type', NotifikasiAudit::class)
                ->where('data->group_id', $groupId)
                ->latest()
                ->first();
        } else {
            $notifUser = $auditor->notifications()
                ->where('type', NotifikasiAudit::class)
                ->latest()
                ->limit(100)
                ->get()
                ->first(function ($notification) use ($judul, $isiPesan, $senderId) {
                    $notifData = $notification->data ?? [];

                    return ($notifData['judul'] ?? null) === $judul
                        && ($notifData['isi_pesan'] ?? null) === $isiPesan
                        && (string) ($notifData['sender_id'] ?? '') === (string) $senderId;
                });
        }

        return array_merge($user, [
            'read_at'     => $notifUser?->read_at,
            'status_baca' => $notifUser && !is_null($notifUser->read_at)
                ? 'Dibaca'
                : 'Belum Dibaca',
        ]);
    })->toArray();

    $data['penerima'] = $penerima;
    $notif->data = $data;

    return view('admin.lihat-notifikasi', compact('notif', 'penerima'));
}

    private function getJudul($subjectKey)
    {
        return match ($subjectKey) {
            'audit'      => 'Pemberitahuan Jadwal Audit 5S',
            'verifikasi' => 'Pemberitahuan Jadwal Verifikasi Audit',
            default      => 'Notifikasi',
        };
    }
}