<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;

// Models
use App\Models\CompanyBranchModel;
use App\Models\RawAttLogModel;
use App\Models\PayrollTransactionModel;
use App\Models\PayrollGroupModel;
use App\Models\AttendanceSummaryModel;


// Entities
use App\Entities\CompanyBranch;
use App\Entities\RawAttLog;
use App\Entities\PayrollTransaction;
use App\Entities\PayrollGroup;
use App\Entities\AttendanceSummary;


// Class Library
use App\ClassLib\MiscLib;
use CodeIgniter\I18n\Time;

class TKController extends BaseController
{
    protected $helpers = ['form'];

    public function index()
    {
        return redirect()->to(base_url('/login'));
    }

    public function attendanceSummary()
    {
        $rawAttLogModel = new RawAttLogModel();

        $data['payrollTransactions'] = (new PayrollTransactionModel())->orderBy('created_at', 'DESC')->findAll();
        $data['payGroups'] = (new PayrollGroupModel())->findAll();

        $rawGetData = $this->request->getGet();

        if($rawGetData != null)
        {
            $data['selectedData'] = $rawGetData;

            $attendanceSummaryModel = new AttendanceSummaryModel();
            
            $empSummaries = $attendanceSummaryModel->where(['paytrans_id'=>$rawGetData['paytrans_id'], 'pay_group_id'=>$rawGetData['pay_group_id']])->findAll();
            
            if($empSummaries == null)
            {
                $data['attendanceSummarySaved'] = false;

                $payTrans = (new PayrollTransactionModel())->find($rawGetData['paytrans_id']);
                $employeeWorkDates = $rawAttLogModel->getEmployeeDaysCount($payTrans->payroll_from, $payTrans->payroll_to);

                $employeeWorkDayCount = [];

                foreach($employeeWorkDates as $employeeWorkDate)
                {
                    if(!isset($employeeWorkDayCount[$employeeWorkDate->dtr_emp_id]))
                        $employeeWorkDayCount[$employeeWorkDate->dtr_emp_id] = [
                            'employee_id' => $employeeWorkDate->employee_id,
                            'dtr_emp_id' => $employeeWorkDate->dtr_emp_id,
                            'employee_name' => $employeeWorkDate->first_name . ' ' . $employeeWorkDate->last_name,
                            'att_work_days' => 0
                        ];

                    $employeeWorkDayCount[$employeeWorkDate->dtr_emp_id]['att_work_days']++;
                }

                $data['employeeWorkDayCount'] = $employeeWorkDayCount;
            }
            else
            {
                $data['attendanceSummarySaved'] = true;

                foreach($empSummaries as $empSummary)
                    $employeeWorkDayCount[] = [
                        'employee_id' => $empSummary->employee_id,
                        'dtr_emp_id' => $empSummary->dtr_emp_id,
                        'employee_name' => $empSummary->employee_name,
                        'att_work_days' => $empSummary->att_work_days
                    ];

                $data['employeeWorkDayCount'] = $employeeWorkDayCount;
            }
        }

        return view('timekeeping/attsummaryview', $data);
    }

    public function attendanceSummarySave($payTransId, $payGroupId)
    {
        $rawData = $this->request->getPost();

        $batchEmpSummary = [];

        foreach($rawData['emp_work_day_count'] as $empWorkDayCount)
        {
            $empSummary = explode('|', $empWorkDayCount);

            $batchEmpSummary[] = [
                'paytrans_id' => $payTransId,
                'pay_group_id' => $payGroupId,
                'employee_id' => $empSummary[0],
                'dtr_emp_id' => $empSummary[1],
                'employee_name' => $empSummary[2],
                'att_work_days' => $empSummary[3]
            ];
        }

        $attSummaryModel = new AttendanceSummaryModel();

        if($attSummaryModel->insertBatch($batchEmpSummary, true))
            return redirect()->back()->with('message', 'Attendance summary saved.');
        else
            return redirect()->back()->with('error', 'Failed to save attendance summary.');
    }

    public function attendanceSummaryDelete($payTransId, $payGroupId)
    {
        $attSummaryModel = new AttendanceSummaryModel();

        if($attSummaryModel->where(['paytrans_id'=>$payTransId, 'pay_group_id'=>$payGroupId])->delete())
            return redirect()->back()->with('message', 'Attendance summary deleted.');
        else
            return redirect()->back()->with('error', 'Failed to delete attendance summary.');
    }

    public function rawAttendanceLogUpload()
    {
        $data['branches'] = (new CompanyBranchModel())->findAll();
        $data['selectedBranch'] = $this->request->getGet('branch_code');
        $data['attFromTo'] = $this->request->getGet('att_from_to');
        $data['attFrom'] = $this->request->getGet('att_from');
        $data['attTo'] = $this->request->getGet('att_to');

        if($data['selectedBranch'] != null && $data['attFromTo'] != null)
        {
            $data['attendanceLog'] = (new RawAttLogModel())->where(['branch_code' => $data['selectedBranch'], 'log_date >='=>$data['attFrom'], 'log_date <='=>$data['attTo']])->findAll();

            $attLogHTMLTable = new \CodeIgniter\View\Table();

            // tblAttLog ID should be initialize in view under JS
            $attLogHTMLTable->setTemplate(MiscLib::adminLTEDataTable1Template('tblAttLog'));

            if($data['attendanceLog'] == null)
                $data['tblAttLog'] = '<p>No attendance log found.</p>';
            else
            {
                $attLogHTMLTable->setHeading('Employee ID', 'Log Date', 'Log Time', 'In/Out', 'Branch');
                foreach($data['attendanceLog'] as $attLog)
                {
                    $attLogHTMLTable->addRow($attLog->dtr_emp_id, $attLog->log_date, $attLog->log_time, ($attLog->log_type) ? 'Out' : 'In', $attLog->branch_code);
                }

                $data['tblAttLog'] = $attLogHTMLTable->generate();
            }
        }

        return view('timekeeping/rawattloguploadview', $data);
    }

    public function rawAttendanceLogUploadFile($selectedBranch, $attendanceFrom, $attendanceTo)
    {
        $rawAttLogModel = new RawAttLogModel();
        $batchRawAttLog = [];

        $file = $this->request->getFile('att_file');

        if ($file->isValid() && ! $file->hasMoved()) {
            $name = $file->getName();
            
            $filePath = WRITEPATH . 'uploads/attendance/' . $selectedBranch . '/' . $name;
            $file->move(WRITEPATH . 'uploads/attendance/' . $selectedBranch, $name, true);

            $data = [];
            $fileHandle = fopen($filePath, 'r');

            if($fileHandle)
            {
                $lineCounter = 0;
                $fileInfo = MiscLib::getAttFileInfo($name);

                if($fileInfo['code'] == "AGL")
                {
                    while (($line = fgets($fileHandle)) !== false) 
                    {
                        if($lineCounter < $fileInfo['skipcount']) 
                        {
                            $lineCounter++;
                            continue;
                        }

                        $lineData = explode("\t", $line);
                        $dateTime = explode(' ', $lineData[6]);

                        // Create DateTime objects for comparison
                        $dateFromFile = Time::createFromFormat('m/d/Y', $dateTime[0]);
                        $attFrom = Time::createFromFormat('Y-m-d', $attendanceFrom);
                        $attTo = Time::createFromFormat('Y-m-d', $attendanceTo);

                        // Check if the date from file falls within the specified range
                        if ($dateFromFile < $attFrom || $dateFromFile > $attTo) {
                            $lineCounter++;
                            continue;
                        }

                        $batchRawAttLog[] = [
                            'dtr_emp_id' => trim(substr($line, 8, 4)),
                            'log_date' => $dateFromFile,
                            'log_time' => $dateTime[1],
                            'log_type' => (trim(substr($line, 38, 2)) == "23") ? 0 : 1,
                            'branch_code' => $selectedBranch,
                            'att_from' => $attendanceFrom,
                            'att_to' => $attendanceTo,
                            'created_at' => Time::now(),
                            'created_by' => auth()->user()->employee_id,
                        ];
                        //54325	3	1372	                      	3	26	12/30/2023 22:00:21

                        $lineCounter++;
                    }
                }
                else if($fileInfo['code'] == "ATTLOG") 
                {
                    while (($line = fgets($fileHandle)) !== false) 
                    {
                        if($lineCounter < $fileInfo['skipcount']) 
                        {
                            $lineCounter++;
                            continue;
                        }

                        // Create DateTime objects for comparison
                        $dateFromFile = Time::createFromFormat('Y-m-d', substr($line, 10, 10));
                        $attFrom = Time::createFromFormat('Y-m-d', $attendanceFrom);
                        $attTo = Time::createFromFormat('Y-m-d', $attendanceTo);

                        // Check if the date from file falls within the specified range
                        if ($dateFromFile < $attFrom || $dateFromFile > $attTo) {
                            $lineCounter++;
                            continue;
                        }

                        $batchRawAttLog[] = [
                            'dtr_emp_id' => trim(substr($line, 0, 9)),
                            'log_date' => substr($line, 10, 10),
                            'log_time' => substr($line, 21, 8),
                            'log_type' => substr($line, 32, 1),
                            'branch_code' => $selectedBranch,
                            'att_from' => $attendanceFrom,
                            'att_to' => $attendanceTo,
                            'created_at' => Time::now(),
                            'created_by' => auth()->user()->employee_id,
                        ];
                        //     1182	2019-10-29 10:32:41	1	0	1	0 
                        $lineCounter++;
                    }
                }

                fclose($fileHandle);

                if(!empty($batchRawAttLog) && $rawAttLogModel->addBatchData($batchRawAttLog, true))                
                    return redirect()->back()->with('message', 'Raw attendance log uploaded. Please check the file if it matches selected date range.');
                else
                    return redirect()->back()->with('error', 'Error uploading raw attendance log.');
            }
            else
                return redirect()->back()->with('error', 'Error reading the file. Please check the file and try again.');
        }
        else
            return redirect()->back()->with('error', 'Error uploading file. Please check the file and try again.');
    }

    public function rawAttendanceLogDelete($branchCode, $logDateFrom, $logDAteTo)
    {
        $attLogModel = new RawAttLogModel();

        $result = $attLogModel
        ->where(['log_date >='=>$logDateFrom, 
                 'log_date <='=>$logDAteTo,
                 'branch_code'=>$branchCode])
        ->delete();

        if($result)
            return redirect()->back()->with('message', 'Raw attendance log deleted.');
        else
            return redirect()->back()->with('error', 'Failed to delete raw attendance log.');
    }
}
