<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Absensi;
use App\Models\Teknisi;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class AbsensiApiController extends Controller
{
    /**
     * Absen masuk untuk teknisi dengan support status.
     */
    public function absenMasuk(Request $request)
    {
        Log::info('Absen Masuk Request:', $request->all());

        $status = $request->input('status', 'hadir');

        $rules = [
            'id_teknisi' => 'required|exists:teknisis,id_teknisi',
            'status'     => 'nullable|in:hadir,izin,sakit',
            'keterangan' => 'nullable|string|max:255',
            'latitude'   => 'nullable|string',
            'longitude'  => 'nullable|string',
        ];

        if ($status === 'hadir') {
            $rules['foto_absen_masuk'] = 'required|image|mimes:jpeg,png,jpg,gif|max:2048';
        } else {
            $rules['foto_absen_masuk'] = 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048';
        }

        if ($status === 'izin') {
            $rules['keterangan'] = 'required|string|max:255';
        }

        $validator = Validator::make($request->all(), $rules, [
            'foto_absen_masuk.required' => 'Foto wajib untuk status Hadir',
            'keterangan.required'       => 'Keterangan wajib untuk status Izin',
        ]);

        if ($validator->fails()) {
            Log::error('Validation failed:', $validator->errors()->toArray());
            return response()->json([
                'success' => false,
                'message' => 'Validasi gagal',
                'errors'  => $validator->errors()
            ], 422);
        }

        try {
            // Cek apakah ada sesi yang masih aktif (belum absen keluar)
            $activeAbsen = Absensi::where('id_teknisi', $request->id_teknisi)
                ->whereNull('jam_keluar')
                ->whereDate('tanggal', Carbon::today())
                ->first();
            
            if ($activeAbsen) {
                return response()->json([
                    'success' => false,
                    'message' => 'Anda masih memiliki sesi absen yang aktif'
                ], 400);
            }

            $data = [
                'id_teknisi' => $request->id_teknisi,
                'tanggal'    => Carbon::now('Asia/Jakarta')->toDateString(),
                'jam_masuk'  => $status === 'hadir' ? Carbon::now('Asia/Jakarta') : null,
                'status'     => $status,
                'keterangan' => $request->keterangan,
                'latitude'   => $request->latitude,
                'longitude'  => $request->longitude,
            ];

            if ($request->hasFile('foto_absen_masuk')) {
    $file = $request->file('foto_absen_masuk');
    $filename = uniqid() . '.' . $file->extension();
    $file->move(public_path('storage/absensi-masuk'), $filename);
    $data['foto_absen_masuk'] = 'absensi-masuk/' . $filename;
}

            $absensi = Absensi::create($data);
            $absensi->load('teknisi');

            return response()->json([
                'success' => true,
                'message' => 'Absen masuk berhasil dicatat',
                'data'    => $absensi
            ], 201);

        } catch (\Exception $e) {
            Log::error('Error in absenMasuk: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal melakukan absen masuk',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Absen keluar untuk teknisi dengan support status.
     */
    public function absenKeluar(Request $request)
    {
        Log::info('Absen Keluar Request:', $request->all());

        $status = $request->input('status', 'hadir');

        $rules = [
            'id_teknisi' => 'required|exists:teknisis,id_teknisi',
            'status'     => 'nullable|in:hadir,izin,sakit',
            'keterangan' => 'nullable|string|max:255',
            'latitude'   => 'nullable|string',
            'longitude'  => 'nullable|string',
        ];

        if ($status === 'hadir') {
            $rules['foto_absen_keluar'] = 'required|image|mimes:jpeg,png,jpg,gif|max:2048';
        } else {
            $rules['foto_absen_keluar'] = 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048';
        }

        if ($status === 'izin') {
            $rules['keterangan'] = 'required|string|max:255';
        }

        $validator = Validator::make($request->all(), $rules, [
            'foto_absen_keluar.required' => 'Foto wajib untuk status Hadir',
            'keterangan.required'        => 'Keterangan wajib untuk status Izin',
        ]);

        if ($validator->fails()) {
            Log::error('Validation failed:', $validator->errors()->toArray());
            return response()->json([
                'success' => false,
                'message' => 'Validasi gagal',
                'errors'  => $validator->errors()
            ], 422);
        }

        try {
            // Cari sesi terbaru yang belum absen keluar
            $absensi = Absensi::where('id_teknisi', $request->id_teknisi)
                ->whereNull('jam_keluar')
                ->orderBy('id_absensi', 'desc')
                ->first();

            if (!$absensi) {
                return response()->json([
                    'success' => false,
                    'message' => 'Tidak ada sesi absen aktif yang ditemukan'
                ], 400);
            }

            $data = ['jam_keluar' => Carbon::now('Asia/Jakarta')];

            if ($request->has('status')) {
                $data['status'] = $status;
            }

            if ($request->has('keterangan')) {
                $data['keterangan'] = $absensi->keterangan
                    ? $absensi->keterangan . ' | ' . $request->keterangan
                    : $request->keterangan;
            }

            if ($request->has('latitude')) {
                $data['latitude'] = $request->latitude;
            }

            if ($request->has('longitude')) {
                $data['longitude'] = $request->longitude;
            }

           if ($request->hasFile('foto_absen_keluar')) {
    $file = $request->file('foto_absen_keluar');
    $filename = uniqid() . '.' . $file->extension();
    $file->move(public_path('storage/absensi-keluar'), $filename);
    $data['foto_absen_keluar'] = 'absensi-keluar/' . $filename;
}

            $absensi->update($data);
            $absensi->load('teknisi');

            return response()->json([
                'success' => true,
                'message' => 'Absen keluar berhasil dicatat',
                'data'    => $absensi
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in absenKeluar: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal melakukan absen keluar',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Mengecek status absensi teknisi hari ini.
     */
    public function checkStatus($id_teknisi)
    {
        try {
            $teknisi = Teknisi::where('id_teknisi', $id_teknisi)->first();

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

            // Ambil sesi terbaru hari ini
            $absensi = Absensi::where('id_teknisi', $id_teknisi)
                ->whereDate('tanggal', Carbon::today())
                ->orderBy('id_absensi', 'desc')
                ->first();

            $status = [
                'sudah_absen_masuk'  => false,
                'sudah_absen_keluar' => false,
                'data_absensi'       => null,
            ];

            if ($absensi) {
                $status['sudah_absen_masuk']  = !empty($absensi->jam_masuk) && empty($absensi->jam_keluar) && $absensi->status === 'hadir';
                $status['sudah_absen_keluar'] = !empty($absensi->jam_keluar);
                $status['data_absensi']       = [
                    'jam_masuk'               => $absensi->jam_masuk,
                    'jam_keluar'              => $absensi->jam_keluar,
                    'jam_masuk_formatted'     => $absensi->jam_masuk_formatted,
                    'jam_keluar_formatted'    => $absensi->jam_keluar_formatted,
                    'durasi_kerja_formatted'  => $absensi->durasi_kerja_formatted,
                    'status'                  => $absensi->status,
                    'keterangan'              => $absensi->keterangan,
                    'lokasi_masuk'            => $absensi->lokasi_masuk ?? '-',
                    'lokasi_valid'            => $absensi->lokasi_valid ?? false,
                    'latitude'                => $absensi->latitude,
                    'longitude'               => $absensi->longitude,
                    'foto_absen_masuk'        => $absensi->foto_absen_masuk,
                    'foto_absen_keluar'       => $absensi->foto_absen_keluar,
                ];
            }

            return response()->json([
                'success' => true,
                'message' => 'Status absensi berhasil diambil',
                'data'    => $status
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in checkStatus: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengecek status absensi',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Mendapatkan riwayat absensi teknisi per bulan
     * dengan field yang sudah diformat untuk blade & Flutter.
     */
    public function riwayat(Request $request)
    {
        try {
            $id_teknisi = $request->query('id_teknisi');

            if (!$id_teknisi) {
                return response()->json([
                    'success' => false,
                    'message' => 'id_teknisi diperlukan'
                ], 400);
            }

            $query = Absensi::where('id_teknisi', $id_teknisi);

            if ($request->has('bulan') && $request->has('tahun')) {
                $query->filterByMonth($request->bulan, $request->tahun);
            }

            $absensis = $query->orderBy('tanggal', 'desc')->get();

            // ── Transform: kirim field yang sudah diformat ──────────────
            $data = $absensis->map(function ($absensi) {
                // Hitung menit telat (jadwal masuk 08:00)
                $menitTelat = 0;
                $terlambat  = false;

                if ($absensi->jam_masuk && $absensi->status === 'hadir') {
                    $jamMasuk   = Carbon::parse($absensi->jam_masuk)->setTimezone('Asia/Jakarta');
                    $jamJadwal  = Carbon::parse(
                        $absensi->tanggal->format('Y-m-d') . ' 08:00:00'
                    )->setTimezone('Asia/Jakarta');

                    if ($jamMasuk->gt($jamJadwal)) {
                        $terlambat  = true;
                        $menitTelat = $jamMasuk->diffInMinutes($jamJadwal);
                    }
                }

                return [
                    'tanggal'                => $absensi->tanggal
                                                    ? $absensi->tanggal->format('Y-m-d')
                                                    : null,
                    'status'                 => $absensi->status,
                    'jam_masuk_formatted'    => $absensi->jam_masuk_formatted,
                    'jam_keluar_formatted'   => $absensi->jam_keluar_formatted,
                    'durasi_kerja_formatted' => $absensi->durasi_kerja_formatted,
                    'terlambat'              => $terlambat,
                    'menit_telat'            => $menitTelat,
                    'keterangan'             => $absensi->keterangan,
                    'latitude'               => $absensi->latitude,
                    'longitude'              => $absensi->longitude,
                ];
            });

            return response()->json([
                'success' => true,
                'message' => 'Riwayat absensi berhasil diambil',
                'data'    => $data
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in riwayat: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengambil riwayat absensi',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Mendapatkan statistik absensi.
     */
    public function statistik(Request $request)
    {
        try {
            $startDate = $request->input('start_date');
            $endDate   = $request->input('end_date');
            $idTeknisi = $request->input('id_teknisi');

            $query = Absensi::query();

            if ($startDate && $endDate) {
                $query->whereBetween('tanggal', [$startDate, $endDate]);
            }

            if ($idTeknisi) {
                $query->where('id_teknisi', $idTeknisi);
            }

            $statistik = [
                'total' => $query->count(),
                'hadir' => (clone $query)->where('status', 'hadir')->count(),
                'sakit' => (clone $query)->where('status', 'sakit')->count(),
                'izin'  => (clone $query)->where('status', 'izin')->count(),
            ];

            return response()->json([
                'success' => true,
                'message' => 'Statistik absensi berhasil diambil',
                'data'    => $statistik
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in statistik: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengambil statistik absensi',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Mendapatkan daftar status absensi yang tersedia.
     */
    public function getStatusOptions()
    {
        return response()->json([
            'success' => true,
            'message' => 'Daftar status absensi berhasil diambil',
            'data'    => [
                'hadir' => 'Hadir',
                'izin'  => 'Izin',
                'sakit' => 'Sakit',
            ]
        ], 200);
    }

    /**
     * Mendapatkan rekap absensi bulanan teknisi.
     */
    public function rekap(Request $request)
    {
        try {
            $id_teknisi = $request->query('id_teknisi');
            $bulan      = (int) $request->query('bulan', date('n'));
            $tahun      = (int) $request->query('tahun', date('Y'));

            if (!$id_teknisi) {
                return response()->json([
                    'success' => false,
                    'message' => 'id_teknisi diperlukan'
                ], 400);
            }

            $absensis = Absensi::where('id_teknisi', $id_teknisi)
                ->whereMonth('tanggal', $bulan)
                ->whereYear('tanggal', $tahun)
                ->get();

            $hadir = $absensis->where('status', 'hadir')->count();
            $izin  = $absensis->where('status', 'izin')->count();
            $sakit = $absensis->where('status', 'sakit')->count();
            $total = $absensis->count();

            // Hitung persentase kehadiran
            $persentase = $total > 0 ? round(($hadir / $total) * 100, 1) : 0;

            // Hitung rata-rata jam masuk
            $hadirItems = $absensis->where('status', 'hadir')
                ->filter(fn($a) => $a->jam_masuk !== null);

            $rataJamMasuk  = '-';
            $rataJamKeluar = '-';
            $rataDurasi    = '-';
            $terlambat     = 0;
            $streak        = 0;

            if ($hadirItems->count() > 0) {
                // Rata-rata masuk
                $totalMasukMenit = $hadirItems->sum(function ($a) {
                    return Carbon::parse($a->jam_masuk)
                        ->setTimezone('Asia/Jakarta')
                        ->hour * 60
                        + Carbon::parse($a->jam_masuk)
                        ->setTimezone('Asia/Jakarta')
                        ->minute;
                });
                $avgMasuk = round($totalMasukMenit / $hadirItems->count());
                $rataJamMasuk = sprintf('%02d:%02d', intdiv($avgMasuk, 60), $avgMasuk % 60);

                // Rata-rata keluar
                $keluarItems = $hadirItems->filter(fn($a) => $a->jam_keluar !== null);
                if ($keluarItems->count() > 0) {
                    $totalKeluarMenit = $keluarItems->sum(function ($a) {
                        return Carbon::parse($a->jam_keluar)
                            ->setTimezone('Asia/Jakarta')
                            ->hour * 60
                            + Carbon::parse($a->jam_keluar)
                            ->setTimezone('Asia/Jakarta')
                            ->minute;
                    });
                    $avgKeluar = round($totalKeluarMenit / $keluarItems->count());
                    $rataJamKeluar = sprintf('%02d:%02d', intdiv($avgKeluar, 60), $avgKeluar % 60);

                    // Rata-rata durasi
                    $totalDurasiMenit = $keluarItems->sum(fn($a) => $a->durasi_kerja);
                    $avgDurasi = round($totalDurasiMenit / $keluarItems->count());
                    $jam   = intdiv($avgDurasi, 60);
                    $menit = $avgDurasi % 60;
                    $rataDurasi = "{$jam}j {$menit}m";
                }

                // Hitung keterlambatan
                $jadwalMasuk = '08:00';
                $terlambat = $hadirItems->filter(function ($a) use ($jadwalMasuk) {
                    $jamMasuk  = Carbon::parse($a->jam_masuk)->setTimezone('Asia/Jakarta');
                    $jamJadwal = Carbon::parse(
                        $a->tanggal->format('Y-m-d') . ' ' . $jadwalMasuk
                    )->setTimezone('Asia/Jakarta');
                    return $jamMasuk->gt($jamJadwal);
                })->count();
            }

            // Hitung streak (berturut-turut hadir dari hari ini mundur)
            $sortedDesc = $absensis->sortByDesc('tanggal');
            foreach ($sortedDesc as $a) {
                if ($a->status === 'hadir') $streak++;
                else break;
            }

            // Nama bulan Indonesia
            $namaBulan = [
                1=>'Januari',2=>'Februari',3=>'Maret',4=>'April',
                5=>'Mei',6=>'Juni',7=>'Juli',8=>'Agustus',
                9=>'September',10=>'Oktober',11=>'November',12=>'Desember'
            ];

            return response()->json([
                'success' => true,
                'message' => 'Rekap absensi berhasil diambil',
                'data'    => [
                    'bulan'           => ($namaBulan[$bulan] ?? $bulan) . ' ' . $tahun,
                    'total_hari_kerja'=> $total,
                    'hadir'           => $hadir,
                    'izin'            => $izin,
                    'sakit'           => $sakit,
                    'persentase'      => $persentase,
                    'rata_masuk'      => $rataJamMasuk,
                    'rata_keluar'     => $rataJamKeluar,
                    'rata_durasi'     => $rataDurasi,
                    'keterlambatan'   => $terlambat,
                    'streak'          => $streak,
                ]
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in rekap: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengambil rekap absensi',
                'error'   => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Mendapatkan status absensi per tanggal dalam 1 bulan (untuk kalender).
     * Response: { "1": "hadir", "5": "izin", "10": "alpha", ... }
     */
    public function kalender(Request $request)
    {
        try {
            $id_teknisi = $request->query('id_teknisi');
            $bulan      = $request->query('bulan', date('n'));
            $tahun      = $request->query('tahun', date('Y'));

            if (!$id_teknisi) {
                return response()->json([
                    'success' => false,
                    'message' => 'id_teknisi diperlukan'
                ], 400);
            }

            $absensis = Absensi::where('id_teknisi', $id_teknisi)
                ->whereMonth('tanggal', $bulan)
                ->whereYear('tanggal', $tahun)
                ->get(['tanggal', 'status']);

            // Map tanggal (angka) => status
            $data = [];
            foreach ($absensis as $absensi) {
                $tgl = (int) Carbon::parse($absensi->tanggal)->format('j');
                $data[$tgl] = $absensi->status;
            }

            return response()->json([
                'success' => true,
                'message' => 'Data kalender berhasil diambil',
                'data'    => $data
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error in kalender: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengambil data kalender',
                'error'   => $e->getMessage()
            ], 500);
        }
    }
}