<?php

namespace Modules\Documents\Controllers;

use App\Controllers\BaseController;
use App\Models\DocumentTypeModel;
use App\Models\EmployeeDocumentModel;
use App\Models\EmployeeDocumentVersionModel;
use App\Models\EmployeeModel;
use Modules\Documents\Services\DocumentExpiryService;
use Modules\Documents\Services\EmployeeDocumentService;

class EmployeeDocumentController extends BaseController
{
    protected EmployeeDocumentModel $documents;
    protected EmployeeDocumentVersionModel $versions;
    protected EmployeeDocumentService $service;
    protected DocumentExpiryService $expiry;
    protected EmployeeModel $employees;
    protected DocumentTypeModel $types;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->documents = new EmployeeDocumentModel();
        $this->versions  = new EmployeeDocumentVersionModel();
        $this->service   = new EmployeeDocumentService();
        $this->expiry    = new DocumentExpiryService();
        $this->employees = new EmployeeModel();
        $this->types     = new DocumentTypeModel();
    }

    public function index()
    {
        $employeeId     = $this->request->getGet('employee_id') ? (int) $this->request->getGet('employee_id') : null;
        $documentTypeId = $this->request->getGet('document_type_id') ? (int) $this->request->getGet('document_type_id') : null;
        $status         = $this->request->getGet('status') ?: 'active';
        $search         = trim((string) $this->request->getGet('q'));
        $today          = date('Y-m-d');

        $documents = $this->documents
            ->select('employee_documents.*, e.full_name, e.employee_number, t.name as type_name, t.code as type_code, t.requires_expiry')
            ->join('employees e', 'e.id = employee_documents.employee_id')
            ->join('document_types t', 't.id = employee_documents.document_type_id')
            ->where('e.deleted_at', null)
            ->scopeForList($employeeId, $documentTypeId, $status, $search ?: null)
            ->orderBy('employee_documents.updated_at', 'DESC')
            ->findAll();

        return view('Modules\Documents\Views\records\index', array_merge($this->baseViewData(), [
            'title'          => 'Employee Documents',
            'documents'      => $documents,
            'employees'      => $this->employees->scopeForList(null, 'active')->orderBy('full_name', 'ASC')->findAll(),
            'types'          => $this->types->getActive(),
            'employeeId'     => $employeeId,
            'documentTypeId' => $documentTypeId,
            'filters'        => compact('search', 'status'),
            'expiry'         => $this->expiry,
            'today'          => $today,
        ]));
    }

    public function expiry()
    {
        $filter = $this->request->getGet('filter') ?: '30';
        $search = trim((string) $this->request->getGet('q'));
        $today  = date('Y-m-d');

        $documents = $this->documents
            ->select('employee_documents.*, e.full_name, e.employee_number, t.name as type_name, t.code as type_code')
            ->join('employees e', 'e.id = employee_documents.employee_id')
            ->join('document_types t', 't.id = employee_documents.document_type_id')
            ->where('e.deleted_at', null)
            ->where('employee_documents.status', 'active')
            ->scopeForList(null, null, 'active', $search ?: null, $filter, $today)
            ->orderBy('employee_documents.expiry_date', $filter === 'expired' ? 'DESC' : 'ASC')
            ->findAll();

        return view('Modules\Documents\Views\records\expiry', array_merge($this->baseViewData(), [
            'title'     => 'Document Expiry Tracker',
            'documents' => $documents,
            'summary'   => $this->expiry->summary($today),
            'filter'    => $filter,
            'filters'   => compact('search'),
            'expiry'    => $this->expiry,
            'today'     => $today,
        ]));
    }

    public function createForm()
    {
        return view('Modules\Documents\Views\records\create', array_merge($this->baseViewData(), [
            'title'     => 'Upload Document',
            'employees' => $this->employees->scopeForList(null, 'active')->orderBy('full_name', 'ASC')->findAll(),
            'types'     => $this->types->getActive(),
        ]));
    }

    public function store()
    {
        if (! $this->validate([
            'employee_id'      => 'required|integer',
            'document_type_id' => 'required|integer',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $result = $this->service->create(
            $this->request->getPost(),
            $this->request->getFile('document_file'),
            (int) $this->session->get('user_id')
        );

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

        $redirect = $this->request->getPost('redirect_to') ?: '/documents/' . $result['id'];

        return redirect()->to($redirect)->with('success', 'Document uploaded successfully.');
    }

    public function show(int $id)
    {
        $document = $this->documents->getWithDetails($id);
        if (! $document) {
            return redirect()->to('/documents')->with('error', 'Document not found.');
        }

        $versions = $this->versions->getForDocument($id);
        $today    = date('Y-m-d');

        return view('Modules\Documents\Views\records\show', array_merge($this->baseViewData(), [
            'title'    => $document['type_name'],
            'document' => $document,
            'versions' => $versions,
            'expiry'   => $this->expiry,
            'today'    => $today,
        ]));
    }

    public function editForm(int $id)
    {
        $document = $this->documents->getWithDetails($id);
        if (! $document) {
            return redirect()->to('/documents')->with('error', 'Document not found.');
        }

        return view('Modules\Documents\Views\records\edit', array_merge($this->baseViewData(), [
            'title'    => 'Edit Document',
            'document' => $document,
        ]));
    }

    public function update(int $id)
    {
        $result = $this->service->update(
            $id,
            $this->request->getPost(),
            $this->request->getFile('document_file'),
            (int) $this->session->get('user_id')
        );

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

        return redirect()->to('/documents/' . $id)->with('success', 'Document updated.');
    }

    public function download(int $id)
    {
        $versionId = $this->request->getGet('version') ? (int) $this->request->getGet('version') : null;
        $file      = $this->service->getDownloadPath($id, $versionId);

        if (! $file) {
            return redirect()->back()->with('error', 'Document file not found.');
        }

        return $this->response->download($file['absolute'], null)->setFileName($file['filename']);
    }

    public function destroy(int $id)
    {
        $result = $this->service->delete($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->to('/documents')->with('error', $result['error']);
        }

        return redirect()->to('/documents')->with('success', 'Document archived.');
    }
}
