<?php

namespace Modules\Employees\Controllers;

use App\Controllers\BaseController;
use App\Models\BranchModel;
use App\Models\DepartmentModel;
use App\Models\EmployeeAssetAssignmentModel;
use App\Models\EmployeeDocumentModel;
use App\Models\EmployeeModel;
use App\Models\AssetTypeModel;
use App\Models\DocumentTypeModel;
use Modules\Employees\Services\EmployeeService;

class EmployeeController extends BaseController
{
    protected EmployeeModel $employees;
    protected EmployeeService $service;
    protected DepartmentModel $departments;
    protected BranchModel $branches;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->employees   = new EmployeeModel();
        $this->service     = new EmployeeService();
        $this->departments = new DepartmentModel();
        $this->branches    = new BranchModel();
    }

    public function index()
    {
        $search       = trim((string) $this->request->getGet('q'));
        $status       = $this->request->getGet('status') ?: null;
        $departmentId = $this->request->getGet('department_id') ?: null;
        $branchId     = $this->request->getGet('branch_id') ?: null;
        $showTrashed  = (bool) $this->request->getGet('trashed');

        $query = $this->employees->scopeForList(
            $search ?: null,
            $status,
            $departmentId ? (int) $departmentId : null,
            $branchId ? (int) $branchId : null,
            $showTrashed
        );
        $employees = $query->orderBy('created_at', 'DESC')->paginate(15);

        return view('Modules\Employees\Views\index', array_merge($this->baseViewData(), [
            'title'          => 'Employees',
            'employees'      => $employees,
            'pager'          => $this->employees->pager,
            'departments'    => $this->departments->orderBy('name', 'ASC')->findAll(),
            'branches'       => $this->branches->orderBy('name', 'ASC')->findAll(),
            'filters'        => compact('search', 'status', 'departmentId', 'branchId', 'showTrashed'),
            'nextEmployeeId' => $this->service->generateEmployeeNumber(),
        ]));
    }

    public function createForm()
    {
        return view('Modules\Employees\Views\create', array_merge($this->baseViewData(), [
            'title'          => 'Add Employee',
            'departments'    => $this->departments->where('status', 'active')->orderBy('name', 'ASC')->findAll(),
            'branches'       => $this->branches->where('status', 'active')->orderBy('name', 'ASC')->findAll(),
            'nextEmployeeId' => $this->service->generateEmployeeNumber(),
        ]));
    }

    public function store()
    {
        $rules = [
            'full_name' => 'required|min_length[2]|max_length[200]',
            'email'     => 'permit_empty|valid_email|max_length[191]',
            'cpr_number'=> 'permit_empty|max_length[20]',
        ];

        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $photo  = $this->request->getFile('photo');
        $cprDoc = $this->request->getFile('cpr_document');

        $result = $this->service->create(
            $this->request->getPost(),
            (int) $this->session->get('user_id'),
            $photo && $photo->isValid() ? $photo : null,
            $cprDoc && $cprDoc->isValid() ? $cprDoc : null
        );

        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/employees/' . $result['id'])->with(
            'success',
            "Employee created with ID: {$result['employee_number']}"
        );
    }

    public function show(int $id)
    {
        $employee = $this->employees->withDeleted()->find($id);
        if (! $employee) {
            return redirect()->to('/employees')->with('error', 'Employee not found.');
        }

        $deptName   = $employee['department_id'] ? ($this->departments->find($employee['department_id'])['name'] ?? '—') : '—';
        $branchName = $employee['branch_id'] ? ($this->branches->find($employee['branch_id'])['name'] ?? '—') : '—';

        $assetModel = new EmployeeAssetAssignmentModel();
        $assets     = $assetModel->getForEmployee($id);
        $documents  = (new EmployeeDocumentModel())->getForEmployee($id);

        return view('Modules\Employees\Views\show', array_merge($this->baseViewData(), [
            'title'       => $employee['full_name'],
            'employee'    => $employee,
            'deptName'    => $deptName,
            'branchName'  => $branchName,
            'assets'      => $assets,
            'assetTypes'  => (new AssetTypeModel())->getActive(),
            'documents'   => $documents,
            'documentTypes' => (new DocumentTypeModel())->getActive(),
        ]));
    }

    public function editForm(int $id)
    {
        $employee = $this->employees->withDeleted()->find($id);
        if (! $employee) {
            return redirect()->to('/employees')->with('error', 'Employee not found.');
        }

        return view('Modules\Employees\Views\edit', array_merge($this->baseViewData(), [
            'title'       => 'Edit Employee',
            'employee'    => $employee,
            'departments' => $this->departments->where('status', 'active')->orderBy('name', 'ASC')->findAll(),
            'branches'    => $this->branches->where('status', 'active')->orderBy('name', 'ASC')->findAll(),
            'nextEmployeeId' => $employee['employee_number'],
        ]));
    }

    public function update(int $id)
    {
        $rules = [
            'full_name' => 'required|min_length[2]|max_length[200]',
            'email'     => 'permit_empty|valid_email|max_length[191]',
            'cpr_number'=> 'permit_empty|max_length[20]',
        ];

        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $photo  = $this->request->getFile('photo');
        $cprDoc = $this->request->getFile('cpr_document');

        $result = $this->service->update(
            $id,
            $this->request->getPost(),
            (int) $this->session->get('user_id'),
            $photo && $photo->isValid() ? $photo : null,
            $cprDoc && $cprDoc->isValid() ? $cprDoc : null
        );

        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/employees/' . $id)->with('success', 'Employee updated successfully.');
    }

    public function uploadPhoto(int $id)
    {
        $file = $this->request->getFile('photo');
        if (! $file) {
            return redirect()->back()->with('error', 'No file selected.');
        }

        $result = $this->service->uploadPhoto($id, $file);
        if (! $result['success']) {
            return redirect()->back()->with('error', $result['error']);
        }

        return redirect()->back()->with('success', 'Photo updated.');
    }

    public function activate(int $id)
    {
        $this->service->activate($id, (int) $this->session->get('user_id'));

        return redirect()->back()->with('success', 'Employee activated.');
    }

    public function deactivate(int $id)
    {
        $this->service->deactivate($id, (int) $this->session->get('user_id'));

        return redirect()->back()->with('success', 'Employee deactivated.');
    }

    public function destroy(int $id)
    {
        $this->service->softDelete($id, (int) $this->session->get('user_id'));

        return redirect()->to('/employees')->with('success', 'Employee moved to trash.');
    }

    public function restore(int $id)
    {
        $this->service->restore($id, (int) $this->session->get('user_id'));

        return redirect()->back()->with('success', 'Employee restored.');
    }
}
