<?php

namespace App\Http\Controllers;

use App\Kegiatan;
use App\KegiatanLog;
use App\Instansi;
use App\User;
use App\JabatanInstansi;
use App\Role;
use App\Notifications\KegiatanDikirimNotification;
use App\Notifications\StatusKegiatanNotification;
use App\Notifications\KegiatanDiteruskanNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;

class KegiatanController extends Controller
{
    // ============================================================
    // PRIVATE HELPERS
    // ============================================================

    /**
     * Ambil path file yang valid dari kegiatan.
     * Return null jika kosong/string kosong.
     */
    private function resolveFile(Kegiatan $kegiatan): ?string
    {
        $file = trim($kegiatan->file_dokumentasi ?? '');
        if ($file !== '') return $file;

        $foto = trim($kegiatan->foto ?? '');
        if ($foto !== '') return $foto;

        return null;
    }

    /**
     * Upload file dengan pengecekan realPath manual (fix Windows/Laragon).
     * Return path tersimpan atau null jika gagal/tidak ada file.
     */
 private function uploadFile(Request $request, string $field = 'file_dokumentasi'): ?string
{
    if (!$request->hasFile($field)) {
        return null;
    }

    $file = $request->file($field);

    if (!$file->isValid()) {
        return null;
    }

    $extension = strtolower($file->getClientOriginalExtension());
    $filename  = \Illuminate\Support\Str::random(40) . '.' . $extension;
    $targetDir = storage_path('app/public/kegiatan');

    if (!file_exists($targetDir)) {
        mkdir($targetDir, 0755, true);
    }

    $file->move($targetDir, $filename);

    return 'kegiatan/' . $filename;
}

    private function kirimNotifKeAdminInstansi(Kegiatan $kegiatan): void
    {
        $adminRole = Role::where('nama_role', 'Admin Instansi')->first();

        if ($adminRole) {
            $admins = User::where('role_id', $adminRole->id)
                ->where('instansi_id', $kegiatan->instansi_id)
                ->get();

            if ($admins->count() > 0) {
                Notification::send($admins, new KegiatanDikirimNotification($kegiatan));
            }
        }
    }

    // ============================================================
    // 1. API DROPDOWN
    // ============================================================

    public function getUnitKerja($instansi_id)
    {
        return JabatanInstansi::where('instansi_id', $instansi_id)
            ->whereNotNull('nama_unit')
            ->pluck('nama_unit')
            ->unique()
            ->values();
    }

    public function getPenanggungJawab($instansi_id, $nama_unit)
    {
        $data = JabatanInstansi::with('user')
            ->where('instansi_id', $instansi_id)
            ->where('nama_unit', $nama_unit)
            ->get()
            ->map(fn($item) => [
                'id'           => $item->id,
                'user_name'    => $item->user ? $item->user->name : 'Tanpa Nama',
                'nama_jabatan' => $item->jabatan,
            ]);

        return response()->json($data);
    }

    // ============================================================
    // 2. DOWNLOAD
    // ============================================================

    public function download($id)
    {
        try {
            $kegiatan = Kegiatan::findOrFail($id);
            $user     = auth()->user();

            if (!$user->isSuperAdmin() && !$user->isAdminInstansi() && $user->id != $kegiatan->user_id) {
                abort(403);
            }

            $file = $this->resolveFile($kegiatan);

            if (!$file) {
                return back()->with('error', 'Tidak ada file untuk diunduh.');
            }

            $filePath = storage_path('app/public/' . $file);

            if (!file_exists($filePath)) {
                return back()->with('error', 'File tidak ditemukan di server.');
            }

            return response()->download($filePath, basename($file));

        } catch (\Exception $e) {
            return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
        }
    }

    // ============================================================
    // 3. INDEX
    // ============================================================

    public function index(Request $request)
    {
        $user  = auth()->user();
        $query = Kegiatan::with(['user', 'jabatanInstansi.instansi', 'jabatanInstansi.user']);

        if ($user->isSuperAdmin()) {
            // lihat semua
        } elseif ($user->isAdminInstansi()) {
            $query->where('instansi_id', $user->instansi_id);
        } else {
            $query->where('user_id', $user->id);
        }

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

        if ($request->filled('instansi_id') && ($user->isSuperAdmin() || $user->isAdminInstansi())) {
            $query->where('instansi_id', $request->instansi_id);
        }

        if ($request->filled('unit_id')) {
            $query->whereHas('jabatanInstansi', fn($q) => $q->where('unit_id', $request->unit_id));
        }

        if ($request->filled('jabatan_id')) {
            $query->where('jabatan_instansi_id', $request->jabatan_id);
        }

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(fn($q) => $q
                ->where('nama_kegiatan', 'like', "%{$search}%")
                ->orWhere('deskripsi', 'like', "%{$search}%")
                ->orWhere('tempat', 'like', "%{$search}%")
            );
        }

        if ($request->filled('tanggal_mulai')) {
            $query->whereDate('tanggal_mulai', '>=', $request->tanggal_mulai);
        }

        if ($request->filled('tanggal_selesai')) {
            $query->whereDate('tanggal_selesai', '<=', $request->tanggal_selesai);
        }

        $sortField   = $request->get('sort_by', 'created_at');
        $sortOrder   = $request->get('order', 'desc');
        $allowedSort = ['created_at', 'tanggal_mulai', 'tanggal_selesai', 'status'];

        $query->orderBy(in_array($sortField, $allowedSort) ? $sortField : 'created_at', $sortOrder);

        $kegiatans    = $query->paginate(10)->withQueryString();
        $instansiList = $user->isSuperAdmin() ? Instansi::orderBy('nama_instansi')->get() : collect();
        $unitList     = collect();

        return view('kegiatan.index', compact('kegiatans', 'instansiList', 'unitList', 'sortField', 'sortOrder'));
    }

    // ============================================================
    // 4. GET ADMIN TUJUAN (API)
    // ============================================================

    public function getAdminTujuan($id)
    {
        try {
            $kegiatan    = Kegiatan::findOrFail($id);
            $currentUser = auth()->user();

            if (!$currentUser->isAdminInstansi() || $currentUser->instansi_id != $kegiatan->instansi_id) {
                return response()->json(['success' => false, 'message' => 'Anda tidak memiliki akses'], 403);
            }

            $adminRole = Role::where('nama_role', 'Admin Instansi')->first();

            if (!$adminRole) {
                return response()->json(['success' => false, 'message' => 'Role Admin Instansi tidak ditemukan'], 404);
            }

            $admins = User::where('role_id', $adminRole->id)
                ->where('instansi_id', $kegiatan->instansi_id)
                ->where('id', '!=', $currentUser->id)
                ->get(['id', 'name', 'email'])
                ->map(fn($a) => [
                    'id'      => $a->id,
                    'name'    => $a->name,
                    'email'   => $a->email,
                    'jabatan' => 'Admin Instansi',
                ]);

            return response()->json(['success' => true, 'admins' => $admins]);

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500);
        }
    }

    // ============================================================
    // 5. CREATE & STORE
    // ============================================================

    public function create()
    {
        if (auth()->user()->isAdminInstansi() || auth()->user()->isSuperAdmin()) {
            abort(403, 'Admin tidak diizinkan membuat kegiatan.');
        }

        $instansi = Instansi::all();
        return view('kegiatan.create', compact('instansi'));
    }

public function store(Request $request)
{
    $request->validate([
        'jabatan_instansi_id' => 'required|exists:jabatan_instansis,id',
        'tanggal'             => 'required|date',
        'nama_kegiatan'       => 'required|string|max:255',
        'deskripsi'           => 'required|string',
        'file_dokumentasi'    => 'nullable|file|mimes:jpg,jpeg,png,pdf,doc,docx,xls,xlsx,ppt,pptx|max:10240',
    ]);

    $jabatanTerpilih = JabatanInstansi::findOrFail($request->jabatan_instansi_id);

    // GANTI: panggil uploadFile(), bukan ->store() langsung
    $path = $this->uploadFile($request);

    $kegiatan = Kegiatan::create([
        'user_id'             => auth()->id(),
        'jabatan_instansi_id' => $request->jabatan_instansi_id,
        'instansi_id'         => $jabatanTerpilih->instansi_id,
        'tanggal'             => $request->tanggal,
        'nama_kegiatan'       => $request->nama_kegiatan,
        'deskripsi'           => $request->deskripsi,
        'file_dokumentasi'    => $path,
        'foto'                => null,
        'status'              => 'terkirim',
    ]);

    KegiatanLog::create([
        'kegiatan_id' => $kegiatan->id,
        'user_id'     => auth()->id(),
        'aksi'        => 'terkirim',
        'catatan'     => 'Laporan kegiatan dikirim oleh ' . auth()->user()->name,
    ]);

    $this->kirimNotifKeAdminInstansi($kegiatan);

    return redirect()->route('kegiatan.index')->with('success', 'Laporan berhasil dikirim.');
}
public function preview($id)
{
    try {
        $kegiatan = Kegiatan::findOrFail($id);
        $user     = auth()->user();

        if (!$user->isSuperAdmin() && !$user->isAdminInstansi() && $user->id != $kegiatan->user_id) {
            abort(403);
        }

        $file = $this->resolveFile($kegiatan);

        if (!$file) {
            abort(404, 'Tidak ada file untuk ditampilkan.');
        }

        $filePath = storage_path('app/public/' . $file);

        if (!file_exists($filePath)) {
            abort(404, 'File tidak ditemukan di server.');
        }

        $mimeType  = mime_content_type($filePath);
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));

        // Office files: arahkan ke Google Docs Viewer
        $officeExt = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
        if (in_array($extension, $officeExt)) {
            $fileUrl = asset('storage/' . $file);
            return redirect('https://docs.google.com/viewer?url=' . urlencode($fileUrl) . '&embedded=true');
        }

        // PDF & gambar: tampilkan inline di browser
        return response()->file($filePath, [
            'Content-Type'        => $mimeType,
            'Content-Disposition' => 'inline; filename="' . basename($file) . '"',
        ]);

    } catch (\Exception $e) {
        abort(500, 'Terjadi kesalahan: ' . $e->getMessage());
    }
}

    // ============================================================
    // 6. EDIT & UPDATE
    // ============================================================

    public function edit($id)
    {
        $kegiatan = Kegiatan::with(['jabatanInstansi', 'user'])->findOrFail($id);
        $user     = auth()->user();

        if (!$user->isSuperAdmin() && !$user->isAdminInstansi() && $user->id != $kegiatan->user_id) {
            abort(403, 'Anda tidak memiliki akses untuk mengedit kegiatan ini.');
        }

        if ($kegiatan->status === 'selesai') {
            return redirect()->route('kegiatan.show', $kegiatan->id)
                ->with('error', 'Kegiatan dengan status selesai tidak dapat diedit.');
        }

        $instansi    = Instansi::all();
        $jabatanList = JabatanInstansi::with('user')
            ->where('instansi_id', $kegiatan->instansi_id)
            ->get();

        return view('kegiatan.edit', compact('kegiatan', 'instansi', 'jabatanList'));
    }

    public function update(Request $request, $id)
    {
        $kegiatan = Kegiatan::findOrFail($id);
        $user     = auth()->user();

        if (!$user->isSuperAdmin() && !$user->isAdminInstansi() && $user->id != $kegiatan->user_id) {
            abort(403, 'Anda tidak memiliki akses untuk mengupdate kegiatan ini.');
        }

        $request->validate([
            'jabatan_instansi_id' => 'required|exists:jabatan_instansis,id',
            'tanggal'             => 'required|date',
            'nama_kegiatan'       => 'required|string|max:255',
            'deskripsi'           => 'required|string',
            'file_dokumentasi'    => 'nullable|file|max:10240',
        ]);

        $data = [
            'jabatan_instansi_id' => $request->jabatan_instansi_id,
            'tanggal'             => $request->tanggal,
            'nama_kegiatan'       => $request->nama_kegiatan,
            'deskripsi'           => $request->deskripsi,
        ];

        if ($request->hasFile('file_dokumentasi')) {
            $newPath = $this->uploadFile($request);

            if ($newPath === 'invalid_ext') {
                return back()->withErrors(['file_dokumentasi' => 'Format file tidak didukung.'])->withInput();
            }

            if ($newPath) {
                $fileLama = $this->resolveFile($kegiatan);
                if ($fileLama) {
                    Storage::disk('public')->delete($fileLama);
                }
                $data['file_dokumentasi'] = $newPath;
                $data['foto']             = null;
            }
        }

        $kegiatan->update($data);

        return redirect()->route('kegiatan.show', $kegiatan->id)
            ->with('success', 'Kegiatan berhasil diperbarui.');
    }

    // ============================================================
    // 7. UPDATE STATUS
    // ============================================================

    public function updateStatus($id, $status)
    {
        $kegiatan = Kegiatan::findOrFail($id);
        $allowed  = ['terkirim', 'sedang', 'selesai'];

        if (!in_array($status, $allowed)) {
            return back()->with('error', 'Status tidak valid.');
        }

        if (!auth()->user()->isAdminInstansi() || auth()->user()->instansi_id != $kegiatan->instansi_id) {
            abort(403);
        }

        $kegiatan->update(['status' => $status]);

        $aksiMap = [
            'sedang'  => 'diproses',
            'selesai' => 'selesai',
        ];

        $catatanMap = [
            'sedang'  => 'Kegiatan mulai diproses oleh ' . auth()->user()->name,
            'selesai' => 'Kegiatan diselesaikan oleh ' . auth()->user()->name,
        ];

        KegiatanLog::create([
            'kegiatan_id' => $kegiatan->id,
            'user_id'     => auth()->id(),
            'aksi'        => $aksiMap[$status] ?? $status,
            'catatan'     => $catatanMap[$status] ?? 'Status diperbarui',
        ]);

        $kegiatan->user->notify(new StatusKegiatanNotification($kegiatan));

        return back()->with('success', 'Status berhasil diperbarui.');
    }

    // ============================================================
    // 8. SHOW
    // ============================================================

    public function show($id)
    {
        $kegiatan = Kegiatan::with([
            'user',
            'jabatanInstansi.instansi',
            'jabatanInstansi.user',
            'logs.user',
            'logs.tujuan',
        ])->findOrFail($id);

        return view('kegiatan.show', compact('kegiatan'));
    }

    // ============================================================
    // 9. TERUSKAN
    // ============================================================

    public function teruskan(Request $request, $id)
    {
        try {
            $request->validate([
                'admin_tujuan_id' => 'required|exists:users,id',
                'catatan'         => 'nullable|string|max:500',
            ]);

            $kegiatan = Kegiatan::findOrFail($id);
            $user     = auth()->user();

            if (!$user->isAdminInstansi() || $user->instansi_id != $kegiatan->instansi_id) {
                return back()->with('error', 'Anda tidak memiliki akses untuk meneruskan kegiatan ini.');
            }

            $adminTujuan = User::findOrFail($request->admin_tujuan_id);

            $adminTujuan->notify(new KegiatanDiteruskanNotification($kegiatan, $user, $request->catatan));

            KegiatanLog::create([
                'kegiatan_id'    => $kegiatan->id,
                'user_id'        => auth()->id(),
                'aksi'           => 'diteruskan',
                'catatan'        => $request->catatan ?? null,
                'tujuan_user_id' => $adminTujuan->id,
            ]);

            return back()->with('success', "Kegiatan berhasil diteruskan ke {$adminTujuan->name}.");

        } catch (\Exception $e) {
            return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
        }
    }

    // ============================================================
    // 10. DESTROY
    // ============================================================

    public function destroy($id)
    {
        $kegiatan = Kegiatan::findOrFail($id);

        if (!auth()->user()->isAdminInstansi() && auth()->id() != $kegiatan->user_id) {
            abort(403);
        }

        $fileLama = $this->resolveFile($kegiatan);
        if ($fileLama) {
            Storage::disk('public')->delete($fileLama);
        }

        $kegiatan->delete();

        return redirect()->route('kegiatan.index')->with('success', 'Laporan dihapus.');
    }
}