<?php

namespace App\Controllers\Mobile\DailyPresence;

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

class Map extends BC
{
    use ResponseTrait;
    private $jl;
    public function index()
    {
        return view('Mobile/DailyPresence/map');
    }
    public function config()
    {
        $sdt = strtotime(" 00:00:00");
        $edt = strtotime(" 23:59:59");
        $map = json_decode(options('attendance_map_data'), true);
        unset($map['staff_radius']);
        $db =  db_connect();
        $map['libur'] = $db->table('jadwal_libur')->where(['is_nasional' => 1, 'tanggal' => date('Y-m-d')])->get()->getRowArray();
        $map['present'] = $db->table('daily_presence_siswa')->select("siswa_id,timeIn,timeOut,status");
        $map['present']->where('siswa_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;
                }
            }

            if ($map['present']['timeOut']) {
                if (date('Y-m-d', $map['present']['timeOut']) != date('Y-m-d') || strlen($map['present']['timeOut']) < 10) {
                    $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 ($map['libur']) {
            $map['libur'] = $map['libur']['title'];
        }
        if (!options('el_mode')) $map['libur'] = "Elearning Mode Is Off";
        $attendance = json_decode(options('attendance_siswa'), 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()
    {
        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_siswa'), 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('daily_presence_siswa')->select("latIn,lonIn,latOut,lonOut,timeIn,timeOut,status");
        $exist->where('siswa_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;
        }
        $isIn = 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 = [
                    'siswa_id' => user()->id,
                    'updated_at' => time(),
                    'created_at' => time()
                ];
                if ($timeOut > time()) {
                    $pd['timeIn'] = time();
                    $pd['latIn'] = $lat;
                    $pd['methodIn'] = 'map';
                    $pd['lonIn'] = $lon;
                    $isIn = true;
                } else {
                    $pd['latOut'] = $lat;
                    $pd['lonOut'] = $lon;
                    $pd['methodOut'] = 'map';
                    $pd['timeOut'] = time();
                    $isIn = false;
                }
                $db->table('daily_presence_siswa')->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;
                    $lat = $exist['latOut'] ?? $lat;
                    $lon = $exist['lonOut'] ?? $lon;
                    $isIn = false;
                    // if (!$exist['timeIn']) $presence['timeIn'] = time();

                    $update = $db->table('daily_presence_siswa')->where('siswa_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;
                    $lat = $exist['latIn'] ?? $lat;
                    $lon = $exist['lonIn'] ?? $lon;
                    $isIn = true;
                    $update = $db->table('daily_presence_siswa')->where('siswa_id', user()->id);
                    $update->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
                    $update->update($presence);
                }
            }
        } else {
            if (!$exist) {
                $pd  = [
                    'siswa_id' => user()->id,
                    'methodIn' => 'map',
                    'latIn' => $lat,
                    'lonIn' => $lon,
                    'timeIn' => time(),
                    'updated_at' => time(),
                    'created_at' => time()
                ];
                $db->table('daily_presence_siswa')->insert($pd);

                $isIn = true;
            } 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;
                    $isIn = true;
                } else {
                    $pd['methodOut'] = 'map';
                    $pd['timeOut'] = time();
                    $pd['latOut'] = $lat;
                    $pd['lonOut'] = $lon;
                    $isIn = false;
                }
                $update = $db->table('daily_presence_siswa')->where('siswa_id', user()->id);
                $update->where("IFNULL(timeIn,timeOut) BETWEEN $sdt AND $edt");
                $update->update($pd);
            }
        }
        if ($db->affectedRows() <= 0) return $this->fail(['message' => "Gagal, silahkan coba lagi"]);
        if (strlen(user()->phone ?? '') < 10 || $isIn == null)  return $this->respond(['message' => "Berhasil"]);
        $wa = json_decode(options('whatsapp'), true);
        if (!$wa['siswa_presensi_masuk'] && $isIn) return $this->respond(['message' => "Berhasil"]);
        elseif (!$wa['siswa_presensi_keluar'] && !$isIn) return $this->respond(['message' => "Berhasil"]);
        if ($isIn) $msg = $wa['message_siswa_presensi_masuk'];
        else $msg = $wa['message_siswa_presensi_keluar'];
        $map = "https://maps.google.com/maps?q=$lat,$lon&hl=id&z=14&amp;output=embed";
        $msg = str_replace('{lokasi}', $lat && $lon ? $map : 'Disekolah', $msg);
        $msg = str_replace('{nama}', user()->nama, $msg);
        $msg = str_replace('{kelas}', user()->nama_kelas, $msg);
        $wadevice = $db->table('whatsapp_device')->where(['status' => '1', 'is_connected' => '1'])->get()->getResultArray();
        if (count($wadevice) == 0) return $this->respond(['message' => "Berhasil"]);
        $device = null;
        $backup_device = null;
        if ($wa['randomize']) {
            $device = $wadevice[random_int(0, count($wadevice) - 1)];
            $bds  = [];
            foreach ($wadevice as $wad) {
                if ($device['id'] == $wad['id']) continue;
                $bds[] = $wad;
            }
            if ($bds) $backup_device = $bds[random_int(0, count($bds) - 1)];
        } else {
            foreach ($wadevice as $wad) {
                if ($wad['is_default']) {
                    $device = $wad;
                    break;
                } else {
                    $backup_device  = $wad;
                }
            }
        }
        if (!$device) return $this->respond(['message' => "Berhasil"]);

        $opt = [
            'number' => user()->phone,
            'message' => $msg,
            'endpoint' => 'send',
        ];
        if (!sendWAMessage($device['device_id'], $opt)['status'] && $backup_device) sendWAMessage($backup_device['device_id']);
        return $this->respond(['message' => "Berhasil"]);
    }
    public function rekap()
    {
        $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('m_siswa ms')->join('daily_presence_siswa dps', "dps.siswa_id=ms.id AND IFNULL(dps.timeIn,dps.timeOut) BETWEEN $sdt AND $edt", 'left');
            $builder->where('ms.id', user()->id)->select("IFNULL(dps.status,2) status,dps.timeIn,dps.timeOut,dps.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;
    }
    private function testTimeIO($data)
    {
        if ($data['timeIn']) if (date("Y-m-d", $data['timeIn']) != date("Y-m-d")) return null;
        if ($data['timeOut']) if (date("Y-m-d", $data['timeOut']) != date("Y-m-d")) return null;
        return $data;
    }
}
