<?php

namespace App\Controllers\Panel\DailyPresence;

use App\Controllers\Panel\BC;
use CodeIgniter\API\ResponseTrait;
use DateInterval;
use DatePeriod;
use DateTime;

class Map extends BC
{
    use ResponseTrait;
    private $jl;
    public function index()
    {
        return view('Panel/DailyPresence/map', ['page_title' => "Presensi"]);
    }
    public function config()
    {
        $tbl = user()->hasRole('guru') ? "daily_presence_guru" : "daily_presence_karyawan";
        $map = json_decode(options('attendance_map_data'), true);
        unset($map['student_radius']);
        $db = db_connect();
        $sdt = strtotime(" 00:00:00");
        $edt = strtotime(" 23:59:59");

        $map['libur'] = $db->table('jadwal_libur')->where(['is_nasional' => 1, 'tanggal' => date('Y-m-d')])->get()->getRowArray();
        $map['present'] = $db->table($tbl)->select("timeIn,timeOut,status");
        $map['present']->where('user_id', user()->id);
        $map['present']->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
        // $map['present']->where("IFNULL(timeIn,UNIX_TIMESTAMP()) >=", strtotime(" 00:00:00"), false);
        // $map['present']->where("IFNULL(timeOut,UNIX_TIMESTAMP()) <=", strtotime(" 23:59:59"), false);
        $map['present'] = $map['present']->orderBy('created_at', 'DESC')->get()->getRowArray();
        if ($map['present']) {
            if ($map['present']['timeIn']) {
                if (date('Y-m-d', $map['present']['timeIn']) != date('Y-m-d') || strlen($map['present']['timeIn']) < 10) {
                    $map['present'] = null;
                }
            } elseif ($map['present']['timeOut']) {
                if (date('Y-m-d', $map['present']['timeOut']) != date('Y-m-d')) {
                    $map['present'] = null;
                }
            }
            if ($map['present']) {
                if (($map['present']['timeOut'] == null || $map['present']['timeOut'] == '0') && $map['present']['timeIn'] == null) $map['present'] = null;
                elseif (($map['present']['timeIn'] == null || $map['present']['timeIn'] == '0') && $map['present']['timeOut'] == null) $map['present'] = null;
            }            // if ((strlen($map['present']['timeIn'] ?? '') < 10 && $map['present']['timeIn'] == null) || (strlen($map['present']['timeOut'] ?? '') < 10 && $map['present']['timeOut'] == null)) $map['present'] = null;
        }
        if ($map['libur']) {
            $map['libur'] = $map['libur']['title'];
        }
        if (!options('el_mode')) $map['libur'] = "Elearning Mode Is Off";
        $attendance = json_decode(options('attendance_staff'), true);
        $map['timeIn'] = parseAttendanceTimeToNow($attendance['timeIn']);
        $map['timeOut'] = parseAttendanceTimeToNow($attendance['timeOut']);
        $map['csrf'] = [
            'name' => csrf_token(),
            'value' => csrf_hash()
        ];
        return $this->respond($map);
    }
    public function present()
    {
        $tbl = user()->hasRole('guru') ? "daily_presence_guru" : "daily_presence_karyawan";
        if (!options('el_mode')) {
            return $this->fail(['message' => "Elearning Mode Is Off"]);
        }
        $sdt = strtotime(" 00:00:00");
        $edt = strtotime(" 23:59:59");
        $db = db_connect();
        $libur = $db->table('jadwal_libur')->where(['is_nasional' => 1, 'tanggal' => date('Y-m-d')])->get()->getRowArray();
        if ($libur) return $this->fail(['message' => "Hari Ini Libur"]);
        $attendance = json_decode(options('attendance_staff'), true);
        $lat = $this->request->getVar('lat') ?? '';
        $lon = $this->request->getVar('lon') ?? '';
        if ((strlen($lat) > 11 | strlen($lon) > 11) && is_https()) return $this->fail(['message' => "Terdeteksi Melakukan Manipulasi Presensi"]);
        $exist = $db->table($tbl)->select("timeIn,timeOut,latIn,lonIn,latOut,lonOut,status");
        $exist->where('user_id', user()->id);
        $exist->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
        // $exist->where('IFNULL(timeIn,UNIX_TIMESTAMP()) >=', strtotime(" 00:00:00"), false);
        // $exist->where("IFNULL(timeOut,UNIX_TIMESTAMP()) <=", strtotime(" 23:59:59"), false);
        $exist = $exist->orderBy('created_at', 'DESC')->get()->getRowArray();

        if ($exist) {
            if ($exist['timeIn'] == null && $exist['timeOut'] == null) $exist = null;
            else if (strlen($exist['timeOut'] ?? '') < 10 && $exist['timeOut'] != null) $exist = null;
            else if (strlen($exist['timeIn'] ?? '') < 10 && $exist['timeIn'] != null) $exist = null;
            else if ($exist['timeIn'] && date('Y-m-d', $exist['timeIn']) != date('Y-m-d')) $exist = null;
            else if ($exist['timeOut'] && date('Y-m-d', $exist['timeOut']) != date('Y-m-d')) $exist = null;
        }
        if ($attendance['timeIn'] && $attendance['timeOut']) {
            $timeIn = parseAttendanceTimeToNow($attendance['timeIn']);
            $timeOut = parseAttendanceTimeToNow($attendance['timeOut']);
            if (strtotime("+2 hours") < $timeIn) return $this->fail(['message' => "Presensi Belum Dimulai"]);
            if (!$exist) {
                $pd = [
                    'user_id' => user()->id,
                    'updated_at' => time(),
                    'created_at' => time()
                ];
                if ($timeOut > time()) {
                    $pd['timeIn'] = time();
                    $pd['latIn'] = $lat;
                    $pd['methodIn'] = 'map';
                    $pd['lonIn'] = $lon;
                } else {
                    $pd['latOut'] = $lat;
                    $pd['lonOut'] = $lon;
                    $pd['methodOut'] = 'map';
                    $pd['timeOut'] = time();
                }
                $db->table($tbl)->insert($pd);
            } else {

                if ($exist['status'] != 1) return $this->fail(['message' => "Tidak Perlu Mengambil Presensi"]);
                if ($timeOut <= time() && !$exist['timeOut']) {
                    $presence = [
                        'timeOut' => time(),
                        'methodOut' => 'map',
                        'updated_at' => time()
                    ];
                    if ($lat && !$exist['latOut']) $presence['latOut'] = $lat;
                    if ($lon && !$exist['lonOut']) $presence['lonOut'] = $lon;
                    // if (!$exist['timeIn']) $presence['timeIn'] = time();
                    $update = $db->table($tbl)->where(['user_id' => user()->id]);
                    $update->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
                    $update->update($presence);
                } else if (!$exist['timeIn']) {
                    $presence = [
                        'timeIn' => time(),
                        'methodOut' => 'map',
                    ];
                    if ($lat && !$exist['latIn']) $presence['latIn'] = $lat;
                    if ($lon && !$exist['lonIn']) $presence['lonIn'] = $lon;
                    $update = $db->table($tbl)->where(['user_id' => user()->id]);
                    $update->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
                    $update->update($presence);
                }
            }
        } else {
            if (!$exist) {
                $db->table($tbl)->insert([
                    'user_id' => user()->id,
                    'methodIn' => 'map',
                    'latIn' => $lat,
                    'lonIn' => $lon,
                    'timeIn' => time(),
                    'updated_at' => time(),
                    'created_at' => time()
                ]);
            } else {
                if ($exist['status'] != 1) return $this->fail(['message' => "Tidak Perlu Mengambil Presensi"]);
                $pd = [
                    'updated_at' => time()
                ];
                if (!$exist['timeIn']) {
                    $pd['timeIn'] = time();
                    $pd['methodIn'] = 'map';
                    $pd['latIn'] = $lat;
                    $pd['lonIn'] = $lon;
                } else {
                    $pd['methodOut'] = 'map';
                    $pd['timeOut'] = time();
                    $pd['latOut'] = $lat;
                    $pd['lonOut'] = $lon;
                }
                $update = $db->table($tbl)->where(['user_id' => user()->id]);
                $update->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
                $update->update($pd);
            }
        }
        if ($db->affectedRows() > 0) return $this->respond(['message' => "Berhasil"]);
        return $this->fail(['message' => "Gagal, silahkan coba lagi"]);
    }
    public function rekap()
    {
        $tbl = user()->hasRole('guru') ? "daily_presence_guru" : "daily_presence_karyawan";
        $types = [
            'izin' => 4,
            'sakit' => 3,
            'alpa' => 2,
            'hadir' => 1,
            'libur' => 0
        ];
        $type = $types[$this->request->getVar('type')] ?? null;
        $begin = new DateTime(date('d-m-Y', strtotime("first day of " . date("Y-m-d H:i:s", $this->request->getVar('date')))));
        $end = new DateTime(date('d-m-Y 00:01', strtotime("last day of " . date("Y-m-d H:i:s", $this->request->getVar('date')))));
        if ($end->format("Y-m") == date('Y-m') && $end->format('d') != date('d')) $end = new DateTime(date('Y-m-d  00:01'));
        $db =  db_connect();
        $interval = DateInterval::createFromDateString('next day');
        $period = new DatePeriod($begin, $interval, $end);
        $parsedDate = date('Y-m');
        $this->jl = $db->table('jadwal_libur')->where(["DATE_FORMAT(tanggal,'%Y-%m')" => "'$parsedDate'", 'is_nasional' => 1], null, false)->get()->getResultArray();
        if ($type == 0) {
            $jl = [];
            foreach ($this->jl as $j) {
                $jl[] = [
                    'timeIn' => strtotime($j['tanggal']),
                    'timeOut' => strtotime($j['tanggal']),
                    'dateTime' => strtotime($parsedDate),
                    'title' => $j['title'],
                    'allDay' => true,
                    'display' => "background",
                ];
            }
            return $this->respond($jl);
        }
        $dataPresensi = [];
        foreach ($period as $k => $dt) {
            $parsedDate = $dt->format("Y-m-d");
            if ($this->is_libur($parsedDate)) continue;
            if ($parsedDate > date("Y-m-d")) continue;
            $sdt = strtotime("$parsedDate 00:00:00");
            $edt = strtotime("$parsedDate 23:59:59");
            $builder = $db->table('users u')->join("$tbl dpg", "dpg.user_id=u.id AND IFNULL(dpg.timeIn,dpg.timeOut) BETWEEN $sdt AND $edt", 'left');
            $builder->where('u.id', user()->id)->select("IFNULL(dpg.status,2) status,dpg.timeIn,dpg.timeOut,dpg.created_at");
            $builder->having('status', $type);
            $d =  $builder->get()->getRowArray();
            if (!$d) continue;
            $ds = [
                'timeIn' => $d['timeIn'],
                'timeOut' => $d['timeOut'],
                'dateTime' => strtotime($parsedDate),
                'allDay' => true,
                'display' => "background",
            ];
            $dataPresensi[] = $ds;
        }
        return $this->respond($dataPresensi);
    }
    private function is_libur($tanggal)
    {
        foreach ($this->jl as $jl) {
            if ($jl['tanggal'] == $tanggal) return true;
        }
        return false;
    }
}
