<?php
namespace App\Controllers;

class Employees extends BaseController
{
    public function index()
    {
        $empQ = $this->db->table('employees e')
            ->select('e.*, u.name, u.email, u.phone, u.status, f.name as facility_name')
            ->join('users u','u.id=e.user_id','left')
            ->join('facilities f','f.id=e.facility_id','left');
        $this->scopeFacilities($empQ, 'e.facility_id');
        $pg        = $this->paginate(25);
        $total     = (clone $empQ)->countAllResults(false);
        $employees = $empQ->orderBy('u.name', 'ASC')->limit($pg['perPage'], $pg['offset'])->get()->getResultArray();

        return view('employees/index', $this->viewData([
            'title'       => 'Workforce',
            'employees'   => $employees,
            'totalCount'  => $total,
            'perPage'     => $pg['perPage'],
            'currentPage' => $pg['page'],
        ]));
    }

    public function create()
    {
        $users = $this->usersByRole('technician');
        $facilities = $this->db->table('facilities')->where('status','active')->get()->getResultArray();
        return view('employees/create', $this->viewData(['title'=>'Add Employee','users'=>$users,'facilities'=>$facilities]));
    }

    public function store()
    {
        $rules = ['designation'=>'required','department'=>'required'];
        if(!$this->validate($rules)) return redirect()->back()->withInput()->with('errors',$this->validator->getErrors());
        $userId = $this->request->getPost('user_id') ?: null;
        $maxId = $this->db->table('employees')->selectMax('id','max_id')->get()->getRowArray();
        $code = 'EMP-'.sprintf('%03d',(($maxId['max_id'] ?? 0) + 1));
        $this->db->table('employees')->insert([
            'user_id'=>$userId,'facility_id'=>$this->request->getPost('facility_id')?:null,
            'emp_code'=>$code,'designation'=>esc($this->request->getPost('designation')),
            'department'=>esc($this->request->getPost('department')),'shift_start'=>$this->request->getPost('shift_start')?:'08:00',
            'shift_end'=>$this->request->getPost('shift_end')?:'17:00','hourly_rate'=>(float)$this->request->getPost('hourly_rate'),
            'hire_date'=>$this->request->getPost('hire_date')?:null,'status'=>'active',
        ]);
        return redirect()->to(base_url('employees'))->with('success','Employee added.');
    }

    public function view(int $id)
    {
        $emp = $this->db->table('employees e')->select('e.*, u.name, u.email, u.phone, f.name as facility_name')
            ->join('users u','u.id=e.user_id','left')->join('facilities f','f.id=e.facility_id','left')
            ->where('e.id',$id)->get()->getRowArray();
        if(!$emp) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        $attendance = $this->db->table('attendance')->where('employee_id',$id)->orderBy('date','DESC')->limit(30)->get()->getResultArray();
        $assignedWO = $this->db->table('work_orders w')
            ->select('w.*,f.name as facility_name')->join('facilities f','f.id=w.facility_id','left')
            ->where('w.assigned_to',$emp['user_id'])->whereIn('w.status',['assigned','in_progress','on_hold'])
            ->get()->getResultArray();
        return view('employees/view', $this->viewData(['title'=>($emp['name']??'Employee'),'emp'=>$emp,'attendance'=>$attendance,'assignedWO'=>$assignedWO]));
    }

    public function edit(int $id)
    {
        $emp = $this->db->table('employees e')->select('e.*, u.name, u.email')
            ->join('users u','u.id=e.user_id','left')->where('e.id',$id)->get()->getRowArray();
        if(!$emp) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        $facilities = $this->db->table('facilities')->where('status','active')->get()->getResultArray();
        return view('employees/edit', $this->viewData(['title'=>'Edit Employee','emp'=>$emp,'facilities'=>$facilities]));
    }

    public function update(int $id)
    {
        $this->db->table('employees')->where('id',$id)->update([
            'facility_id'=>$this->request->getPost('facility_id')?:null,'designation'=>esc($this->request->getPost('designation')),
            'department'=>esc($this->request->getPost('department')),'shift_start'=>$this->request->getPost('shift_start'),
            'shift_end'=>$this->request->getPost('shift_end'),'hourly_rate'=>(float)$this->request->getPost('hourly_rate'),
            'status'=>$this->request->getPost('status'),
        ]);
        return redirect()->to(base_url('employees'))->with('success','Employee updated.');
    }

    public function delete(int $id)
    {
        $this->db->table('employees')->where('id',$id)->update(['status'=>'inactive']);
        return redirect()->to(base_url('employees'))->with('success','Employee deactivated.');
    }

    public function checkin()
    {
        $uid = session()->get('user_id');
        $emp = $this->db->table('employees')->where('user_id',$uid)->get()->getRowArray();
        if (!$emp) return $this->response->setJSON(['status'=>false,'message'=>'Employee not found']);

        $today = date('Y-m-d');
        $existing = $this->db->table('attendance')->where('employee_id',$emp['id'])->where('date',$today)->get()->getRowArray();

        $lat = (float)$this->request->getPost('latitude');
        $lng = (float)$this->request->getPost('longitude');

        if ($existing && !$existing['check_in']) {
            $this->db->table('attendance')->where('id',$existing['id'])->update([
                'check_in'  => date('Y-m-d H:i:s'),
                'latitude'  => $lat ?: null,
                'longitude' => $lng ?: null,
                'status'    => 'present',
            ]);
        } elseif (!$existing) {
            $this->db->table('attendance')->insert([
                'employee_id' => $emp['id'],
                'date'        => $today,
                'check_in'    => date('Y-m-d H:i:s'),
                'latitude'    => $lat ?: null,
                'longitude'   => $lng ?: null,
                'status'      => 'present',
            ]);
        }
        return $this->response->setJSON(['status'=>true,'message'=>'Checked in at '.date('H:i')]);
    }

    public function checkout()
    {
        $uid = session()->get('user_id');
        $emp = $this->db->table('employees')->where('user_id',$uid)->get()->getRowArray();
        if (!$emp) return $this->response->setJSON(['status'=>false,'message'=>'Employee not found']);

        $today = date('Y-m-d');
        $record = $this->db->table('attendance')->where('employee_id',$emp['id'])->where('date',$today)->get()->getRowArray();
        if (!$record) return $this->response->setJSON(['status'=>false,'message'=>'No check-in found for today']);

        $reason = esc($this->request->getPost('reason') ?? '');
        $checkIn = strtotime($record['check_in']);
        $checkOut = time();
        $hoursWorked = round(($checkOut - $checkIn) / 3600, 2);

        $shiftEnd = strtotime(date('Y-m-d') . ' ' . ($emp['shift_end'] ?? '17:00:00'));
        $overtime = max(0, round(($checkOut - $shiftEnd) / 3600, 2));

        $this->db->table('attendance')->where('id',$record['id'])->update([
            'check_out'    => date('Y-m-d H:i:s'),
            'hours_worked' => $hoursWorked,
            'overtime_hrs' => $overtime,
            'early_reason' => $reason,
        ]);
        return $this->response->setJSON(['status'=>true,'message'=>'Checked out. Hours: '.$hoursWorked, 'overtime'=>$overtime]);
    }

    public function startBreak()
    {
        $uid = session()->get('user_id');
        $emp = $this->db->table('employees')->where('user_id',$uid)->get()->getRowArray();
        if (!$emp) return $this->response->setJSON(['status'=>false,'message'=>'Employee not found']);

        $this->db->table('employee_breaks')->insert([
            'employee_id' => $emp['id'],
            'break_start' => date('Y-m-d H:i:s'),
            'date'        => date('Y-m-d'),
        ]);
        return $this->response->setJSON(['status'=>true,'message'=>'Break started']);
    }

    public function endBreak()
    {
        $uid = session()->get('user_id');
        $emp = $this->db->table('employees')->where('user_id',$uid)->get()->getRowArray();
        $break = $this->db->table('employee_breaks')->where('employee_id',$emp['id'])->where('date',date('Y-m-d'))->where('break_end',null)->orderBy('id','DESC')->limit(1)->get()->getRowArray();
        if ($break) {
            $mins = round((time() - strtotime($break['break_start'])) / 60);
            $this->db->table('employee_breaks')->where('id',$break['id'])->update(['break_end'=>date('Y-m-d H:i:s'),'duration_mins'=>$mins]);
        }
        return $this->response->setJSON(['status'=>true,'message'=>'Break ended']);
    }

    public function attendance()
    {
        $empId = $this->request->getGet('emp_id');
        $month = $this->request->getGet('month') ?? date('Y-m');

        $q = $this->db->table('attendance a')
            ->select('a.*, e.emp_code, u.name')
            ->join('employees e','e.id=a.employee_id','left')
            ->join('users u','u.id=e.user_id','left');

        if ($empId) $q->where('a.employee_id', $empId);
        $q->like('a.date', $month, 'after');
        $records = $q->orderBy('a.date','DESC')->get()->getResultArray();

        $employees = $this->db->table('employees e')->select('e.id, u.name')->join('users u','u.id=e.user_id','left')->where('e.status','active')->get()->getResultArray();

        return view('employees/attendance', $this->viewData(['title'=>'Attendance','records'=>$records,'employees'=>$employees,'month'=>$month,'selectedEmp'=>$empId]));
    }
}
