<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/* * ***************Api.php**********************************
 * @product name    : Hospital Management System
 * @type            : Class
 * @class name      : Api
 * @description     : This class used to handle attendence functionality 
 *                    of the application.  
 * @author          : South Bangla IT Zone Team 	
 * @url             : http://hms.sbitzone.com/  
 * @support         : rabibd.it@gmail.com	
 * @copyright       : South Bangla IT Zone Team	
 * ********************************************************** */
class Api extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('Dashboard_Model', 'dashboard', true);

        $this->global_setting = $this->db->get_where('global_setting', array('status' => 1))->row();
        if ($this->global_setting) {
            date_default_timezone_set($this->global_setting->time_zone);
        }
    }

    public function attendance() {
        $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
        if (strcasecmp($contentType, 'application/json') != 0) {
            $this->output
                ->set_status_header(400)
                ->set_content_type('application/json', 'utf-8')
                ->set_output(json_encode([
                    'status'  => FALSE,
                    'message' => 'Content type must be: application/json'
                ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))
                ->_display();
            exit;
        }

        $content = trim(file_get_contents("php://input"));
        $decoded = json_decode($content);

        if (!$decoded) {
            $this->output
                ->set_status_header(404)
                ->set_content_type('application/json', 'utf-8')
                ->set_output(json_encode([
                    'status'  => FALSE,
                    'message' => 'Received content contained invalid JSON!'
                ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))
                ->_display();
            exit;
        }

        $log_id = $this->dashboard->insert('device_logs', ['request' => $content, 'created_at' => date('Y-m-d H:i:s')]);
        $logs = $decoded->data;
        if (empty($logs)) {
            $this->output
                ->set_status_header(400)
                ->set_content_type('application/json', 'utf-8')
                ->set_output(json_encode([
                    'status'  => FALSE,
                    'message' => 'No logs data found!!!'
                ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))
                ->_display();
            exit;
        }

        $rec = [];
        $rej = [];
        foreach ($logs as $row) {
            if (!isset($row->id) || !isset($row->id)) {
                continue;
            }

            $dev_time = new DateTime($row->time);
            $employee = $this->dashboard->getEmployeeByDeviceId($row->id);


            if (!$employee) {
                if (!in_array($row->id, $rej))
                    array_push($rej, $row->id);
                continue;
            }
            if (!in_array($row->id, $rec))
                array_push($rec, $row->id);

            $shift =  $this->dashboard->get_single('shifts', array('status' => 1, 'id' => $employee->shift_id));
            $condition['user_id'] = $employee->user_id;
            $condition['shift_id'] = $employee->shift_id;
            $condition['date'] =  $dev_time->format("Y-m-d");

            if ($shift && $shift->out_next_day) {
                $temp_start_date = new DateTime($dev_time->format("Y-m-d") . ' 00:00:00');
                $temp_end_date = new DateTime($dev_time->format("Y-m-d") . ' ' . $shift->out_time);
                $start_range = $temp_start_date->getTimestamp();
                $end_range = $temp_end_date->add(new DateInterval('PT2H'))->getTimestamp();

                if ($start_range <= $dev_time->getTimestamp() && $end_range >= $dev_time->getTimestamp()) {
                    $condition['date'] = (new DateTime($dev_time->format("Y-m-d")))->sub(new DateInterval('P1D'))->format('Y-m-d');
                }
            }

            $attendance = $this->dashboard->get_single('attendances', $condition);
            if ($attendance) {

                if (empty($attendance->clock_in)) {
                    $update_data['clock_in'] = $dev_time->format("H:i:s");
                } else {
                    $update_data['clock_out'] = $dev_time->format("H:i:s");
                }

                if (empty($attendance->clock_in) && strtotime($shift->absent_time) < strtotime($dev_time->format("H:i:s"))) {
                    $update_data['attendance_status'] = 'a';
                } else {
                    $update_data['attendance_status'] = 'p';
                }

                // Early Leave
                if ($attendance->clock_in && $update_data['clock_out'] && $shift->early_out_allow == 0 && strtotime($shift->out_time) > strtotime($dev_time->format("H:i:s"))) {
                    $out_time = new DateTime($shift->out_time);
                    $dev_out_time   = new DateTime($dev_time->format("H:i:s"));
                    $earlyDiff  = $out_time->diff($dev_out_time);
                    $update_data['early_leaving'] = $earlyDiff->format("%H:%I:%S");
                } else {
                    $update_data['early_leaving'] = null;
                }

                // Overtime
                if (strtotime($dev_time->format("H:i:s")) > strtotime($shift->out_time)) {
                    $overtime = new DateTime($shift->out_time);
                    $dev_overtime   = new DateTime($dev_time->format("H:i:s"));
                    $overtimeDiff  = $dev_overtime->diff($overtime);
                    $update_data['overtime'] = $overtimeDiff->format("%H:%I:%S");
                } else {
                    $update_data['overtime'] = null;
                }

                // Total Hour
                if ($shift->out_next_day) {
                    $clock_in_date = (new DateTime($attendance->date))->sub(new DateInterval('P1D'))->format('Y-m-d');
                    $intime = $clock_in_date . ' ' . $attendance->clock_in;
                    $outtime = $dev_time->format("Y-m-d") . ' ' . $update_data['clock_out'];
                } else {
                    $intime = $attendance->date . ' ' . $attendance->clock_in;
                    $outtime = $dev_time->format("Y-m-d") . ' ' . $update_data['clock_out'];
                }
                $clock_in = new DateTime($intime);
                $clock_out   = new DateTime($outtime);
                $totalDiff  = $clock_out->diff($clock_in);

                if ($attendance->clock_in && $update_data['clock_out']) {
                    $update_data['total'] = $totalDiff->format("%H:%I:%S");
                } else {
                    $update_data['total'] = null;
                }

                $conditions['user_id'] = $employee->user_id;
                $conditions['shift_id'] = $employee->shift_id;
                $conditions['date'] = $attendance->date;
                $this->dashboard->update("attendances", $update_data, $conditions);
            } else {
                if ($dev_time->format("H:i:s") && $shift->late_allow == 1 && strtotime($shift->late_time) < strtotime($dev_time->format("H:i:s"))) {
                    $in_time = new DateTime($shift->in_time);
                    $dev_in_time   = new DateTime($dev_time->format("H:i:s"));
                    $lateDiff  = $in_time->diff($dev_in_time);
                    $data['late'] = $lateDiff->format("%H:%I:%S");
                } else {
                    $data['late'] = null;
                }

                $data['user_id'] = $employee->user_id;
                $data['shift_id'] = $employee->shift_id;
                $data['date'] = $dev_time->format("Y-m-d");
                $data['is_manual'] = 0; // 0 = Machine, 1 = Manual
                $data['punch_type'] = 'finger';
                $data['clock_in'] = $dev_time->format("H:i:s");
                if (strtotime($shift->absent_time) < strtotime($dev_time->format("H:i:s"))) {
                    $data['attendance_status'] = 'a';
                } else {
                    $data['attendance_status'] = 'p';
                }
                $data['status'] = 1;
                $data['created_at'] = date('Y-m-d H:i:a');
                $this->dashboard->insert("attendances", $data);
            }
        }
        sort($rec);
        sort($rej);
        $this->dashboard->update('device_logs', ['received' => json_encode($rec), 'rejected' => json_encode($rej)], ["id" => $log_id]);
        $this->output
            ->set_status_header(200)
            ->set_content_type('application/json', 'utf-8')
            ->set_output(json_encode([
                'status'  => TRUE,
                'message' => 'Success'
            ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))
            ->_display();
        exit;
    }
}
