<?php

namespace App\Http\Controllers;

use App\Exports\LaporanExport;
use App\Models\Laporan;
use App\Models\LaporanDetail;
use App\Models\Karyawan;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Encoders\JpegEncoder;

class LaporanController extends Controller
{
    public function getData(Request $request)
    {
        $bulan = $request->bulan ?? date('n');
        $tahun = $request->tahun ?? date('Y');
        $perPage = (int) $request->get('perPage', 10);
        $search = $request->get('search');

        $request->validate([
            'bulan' => 'nullable|integer|min:1|max:12',
            'tahun' => 'nullable|integer|min:2000|max:2100'
        ]);

        $query = Laporan::with([
            'gl:id,nama',
            'manpower:id,nama'
        ]);


        if (Auth::check() && Auth::user()->role !== 'administrator') {
            $query->where('gl_id', Auth::id());
        }

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('nama_gl', 'like', "%{$search}%")
                    ->orWhere('nama_manpower', 'like', "%{$search}%")
                    ->orWhere('departemen', 'like', "%{$search}%");
            });
        }

        $data = $query
            ->whereBetween('tanggal', [
                Carbon::create($tahun, $bulan, 1)->startOfMonth(),
                Carbon::create($tahun, $bulan, 1)->endOfMonth(),
            ])
            ->latest()
            ->paginate($perPage);

        $data->getCollection()->transform(function ($item) {
            $item->tanggal = $item->tanggal->format('Y-m-d');
            return $item;
        });

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

    public function index()
    {
        $bulan = date('n');
        $tahun = date('Y');

        return view('menu.laporan.index', [
            'bulan' => $bulan,
            'tahun' => $tahun
        ]);
    }

    public function create()
    {
        $user = Auth::user();

        $bulanIni = now()->month;
        $tahunIni = now()->year;

        $manpowers = Karyawan::with(['atr', 'jabatan', 'departemen',])
            ->where('atasan_id', $user->karyawan_id)
            ->whereDoesntHave('laporanManpower', function ($query) use ($bulanIni, $tahunIni) {
                $query->whereBetween('tanggal', [
                    Carbon::create($tahunIni, $bulanIni, 1)->startOfMonth(),
                    Carbon::create($tahunIni, $bulanIni, 1)->endOfMonth(),
                ]);
            })
            ->select('id', 'nama', 'jabatan_id', 'departemen_id')
            ->orderBy('nama', 'asc')
            ->get();

        return view('menu.laporan.create', compact('manpowers'));
    }

    public function createv2()
    {
        $atasans = Karyawan::whereHas('user', function ($q) {
            $q->whereIn('role', ['atasan', 'administrator']);
        })
            ->whereRaw('LOWER(nama) != ?', ['administrator'])
            ->select('id', 'nama')
            ->orderBy('nama')
            ->get();

        $manpowers = Karyawan::with(['atr', 'jabatan', 'departemen'])
            ->select('id', 'nama', 'atasan_id', 'jabatan_id', 'departemen_id')
            ->orderBy('nama')
            ->get();

        return view(
            'menu.laporan.createv2',
            compact('atasans', 'manpowers')
        );
    }

    public function store(Request $request)
    {
        $request->validate([
            'tanggal' => 'required|date',
            'manpower_id' => 'required|exists:karyawans,id',
            'penilaian.*.status' => 'required|in:0,1',
            'foto' => 'nullable|image|max:2048'
        ]);

        $user = Auth::user();

        $manpower = Karyawan::with([
            'jabatan',
            'departemen'
        ])->findOrFail($request->manpower_id);

        // Upload foto
        $fotoPath = null;

        if ($request->hasFile('foto')) {

            $manager = new ImageManager(Driver::class);

            $image = $manager->decode(
                $request->file('foto')
            );

            $image = $image->scale(width: 600);

            do {
                $filename = 'laporan_fotos/' .
                    now()->format('YmdHis') .
                    '_' .
                    Str::random(10) .
                    '.jpg';
            } while (Storage::disk('public')->exists($filename));

            $encoded = $image->encode(
                new JpegEncoder(quality: 75)
            );

            Storage::disk('public')->put(
                $filename,
                (string) $encoded
            );

            $fotoPath = $filename;
        }

        do {

            $slug = 'LPR-' .
                now()->format('Ymd') .
                '-' .
                Str::upper(Str::random(5));
        } while (Laporan::where('slug', $slug)->exists());

        $laporan = Laporan::create([
            'tanggal' => $request->tanggal,
            'gl_id' => $user->karyawan->id,
            'manpower_id' => $manpower->id,

            'nama_gl' => $user->karyawan->nama,
            'departemen' => $manpower->departemen?->departemen,
            'nama_manpower' => $manpower->nama,
            'jabatan' => $manpower->jabatan?->jabatan,

            'note' => $request->note,
            'feedback' => $request->feedback,
            'foto' => $fotoPath,
            'slug' => $slug,
            'user_id' => $user->id
        ]);

        $kategoris = [
            'SHE Culture',
            'ATR',
            'Incident',
            'Manpower Behavior'
        ];

        foreach ($kategoris as $kategori) {
            $key = Str::slug($kategori);

            $status = $request->input("penilaian.{$key}.status");
            $keterangan = $request->input("penilaian.{$key}.keterangan");

            if ($status == '0' && empty($keterangan)) {
                return back()->withInput()->withErrors([
                    'keterangan' => "Keterangan wajib untuk {$kategori}"
                ]);
            }

            LaporanDetail::create([
                'laporan_id' => $laporan->id,
                'kategori' => $kategori,
                'status' => $status,
                'keterangan' => $keterangan
            ]);
        }

        return redirect()->route('laporan.index')
            ->with('success', 'Laporan berhasil disimpan.');
    }

    public function storev2(Request $request)
    {
        $request->validate([
            'tanggal' => 'required|date',
            'gl_id' => 'required|exists:karyawans,id',
            'manpower_id' => 'required|exists:karyawans,id',
            'penilaian.*.status' => 'required|in:0,1',
            'foto' => 'nullable|image|max:2048'
        ]);

        $user = Auth::user();
        $gl = Karyawan::findOrFail($request->gl_id);

        $manpower = Karyawan::with([
            'jabatan',
            'departemen'
        ])->findOrFail($request->manpower_id);

        if ($manpower->atasan_id != $gl->id) {
            abort(403, 'Manpower tidak sesuai dengan GL yang dipilih.');
        }

        // Upload foto
        $fotoPath = null;

        if ($request->hasFile('foto')) {

            $manager = new ImageManager(Driver::class);

            $image = $manager->decode(
                $request->file('foto')
            );

            $image = $image->scale(width: 600);

            do {
                $filename = 'laporan_fotos/' .
                    now()->format('YmdHis') .
                    '_' .
                    Str::random(10) .
                    '.jpg';
            } while (Storage::disk('public')->exists($filename));

            $encoded = $image->encode(
                new JpegEncoder(quality: 75)
            );

            Storage::disk('public')->put(
                $filename,
                (string) $encoded
            );

            $fotoPath = $filename;
        }

        do {

            $slug = 'LPR-' .
                now()->format('Ymd') .
                '-' .
                Str::upper(Str::random(5));
        } while (Laporan::where('slug', $slug)->exists());

        $laporan = Laporan::create([
            'tanggal' => $request->tanggal,
            'user_id' => $user->id,
            'gl_id' => $gl->id,
            'manpower_id' => $manpower->id,

            'nama_gl' => $gl->nama,
            'nama_manpower' => $manpower->nama,
            'jabatan' => $manpower->jabatan?->jabatan,
            'departemen' => $manpower->departemen?->departemen,

            'note' => $request->note,
            'feedback' => $request->feedback,
            'foto' => $fotoPath,
            'slug' => $slug,
            'konfirmasi_status' => 'sesuai',
            'dikonfirmasi_at' => now(),
            'catatan_konfirmasi' => '',

        ]);

        $kategoris = [
            'SHE Culture',
            'ATR',
            'Incident',
            'Manpower Behavior'
        ];

        foreach ($kategoris as $kategori) {
            $key = Str::slug($kategori);

            $status = $request->input("penilaian.{$key}.status");
            $keterangan = $request->input("penilaian.{$key}.keterangan");

            if ($status == '0' && empty($keterangan)) {
                return back()->withInput()->withErrors([
                    'keterangan' => "Keterangan wajib untuk {$kategori}"
                ]);
            }

            LaporanDetail::create([
                'laporan_id' => $laporan->id,
                'kategori' => $kategori,
                'status' => $status,
                'keterangan' => $keterangan
            ]);
        }

        return redirect()->route('laporan.index')
            ->with('success', 'Laporan berhasil disimpan.');
    }

    public function storeKonfirmasi(Request $request, $id)
    {
        $laporan = Laporan::findOrFail($id);

        $laporan->update([
            'konfirmasi_status'  => $request->konfirmasi_status,
            'catatan_konfirmasi' => $request->catatan_konfirmasi,
            'dikonfirmasi_at' => now(),
        ]);

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

    public function show(Laporan $laporan)
    {
        $laporan->load(['details', 'gl', 'manpower.atr']);

        return view('menu.laporan.show', compact('laporan'));
    }

    public function export(Request $request)
    {
        return Excel::download(
            new LaporanExport(
                $request->bulan,
                $request->tahun,
            ),
            'laporan.xlsx'
        );
    }
}
