<?php

class DocumentController extends Controller
{
    private Document $documents;

    public function __construct()
    {
        $this->documents = new Document();
    }

    public function index(): void
    {
        Auth::requireLogin();
        $search = trim($_GET['search'] ?? '');
        $user=Auth::user();
        $role=$user['role']??'';
        if($role==='driver'){$documents=$this->documents->forDriver((int)($user['driver_id']??0));}
        elseif($role==='carrier'){$documents=$this->documents->forCarrier((int)($user['carrier_id']??0));}
        else{$documents=$this->documents->all($search?:null);}
        $this->view('documents/index', compact('documents', 'search'));
        clear_old();
    }

    public function create(): void
    {
        Auth::requireLogin();
        if (in_array(current_role(),['driver','carrier'],true)) { http_response_code(403); require app_path('Views/errors/403.php'); exit; }
        $relatedType = $_GET['related_type'] ?? 'load';
        $relatedId = (int) ($_GET['related_id'] ?? 0);
        $this->view('documents/create', compact('relatedType', 'relatedId'));
    }

    public function store(): void
    {
        Auth::requireLogin();
        if (in_array(current_role(),['driver','carrier'],true)) { http_response_code(403); require app_path('Views/errors/403.php'); exit; }
        Csrf::verify();

        $type = $_POST['related_type'] ?? '';
        $relatedId = (int) ($_POST['related_id'] ?? 0);
        if (!in_array($type, Document::RELATED_TYPES, true) || $relatedId <= 0 || empty(trim($_POST['document_type'] ?? ''))) {
            set_old($_POST);
            $this->flash('danger', 'Document type, related record, and file are required.');
            $this->redirect('/documents/create');
        }

        if (empty($_FILES['file']['tmp_name']) || ($_FILES['file']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
            set_old($_POST);
            $this->flash('danger', 'Please choose a valid file to upload.');
            $this->redirect('/documents/create?related_type=' . urlencode($type) . '&related_id=' . $relatedId);
        }

        $file = $_FILES['file'];
        $maxSize = 10 * 1024 * 1024;
        if (($file['size'] ?? 0) > $maxSize) {
            $this->flash('danger', 'File is too large. Maximum allowed size is 10 MB.');
            $this->redirect('/documents/create?related_type=' . urlencode($type) . '&related_id=' . $relatedId);
        }

        $original = basename((string) $file['name']);
        $extension = strtolower(pathinfo($original, PATHINFO_EXTENSION));
        $allowed = ['pdf', 'jpg', 'jpeg', 'png', 'webp', 'gif', 'heic', 'doc', 'docx'];
        if (!in_array($extension, $allowed, true)) {
            $this->flash('danger', 'Allowed files: PDF, images, DOC, and DOCX.');
            $this->redirect('/documents/create?related_type=' . urlencode($type) . '&related_id=' . $relatedId);
        }

        $folder = storage_path('uploads/documents/' . date('Y/m'));
        if (!is_dir($folder)) {
            mkdir($folder, 0755, true);
        }

        $stored = bin2hex(random_bytes(16)) . '.' . $extension;
        $target = $folder . DIRECTORY_SEPARATOR . $stored;
        if (!move_uploaded_file($file['tmp_name'], $target)) {
            $this->flash('danger', 'Upload failed. Please check storage folder permissions.');
            $this->redirect('/documents/create?related_type=' . urlencode($type) . '&related_id=' . $relatedId);
        }

        $relativePath = str_replace(base_path() . DIRECTORY_SEPARATOR, '', $target);
        $this->documents->create([
            'related_type' => $type,
            'related_id' => $relatedId,
            'document_type' => trim($_POST['document_type']),
            'file_name' => $original,
            'stored_name' => $stored,
            'file_path' => $relativePath,
            'mime_type' => $file['type'] ?? null,
            'file_size' => $file['size'] ?? null,
            'expires_at' => $_POST['expires_at'] ?? null,
            'notes' => $_POST['notes'] ?? null,
            'latitude' => $_POST['latitude'] ?? null,
            'longitude' => $_POST['longitude'] ?? null,
            'location_address' => $_POST['location_address'] ?? null,
        ]);

        log_activity('document_uploaded', 'Uploaded ' . $original);
        $this->flash('success', 'Document uploaded successfully.');
        $this->redirect('/documents');
    }

    public function download(): void
    {
        Auth::requireLogin();
        $document = $this->documents->find((int) ($_GET['id'] ?? 0));
        if (!$document) {
            $this->flash('danger', 'Document not found.');
            $this->redirect('/documents');
        }
        $user=Auth::user();
        if (($user['role']??'')==='driver' && !$this->documents->driverCanAccess((int)$document['id'],(int)($user['driver_id']??0))) {
            http_response_code(403); require app_path('Views/errors/403.php'); exit;
        }
        if (($user['role']??'')==='carrier' && !$this->documents->carrierCanAccess((int)$document['id'],(int)($user['carrier_id']??0))) {
            http_response_code(403); require app_path('Views/errors/403.php'); exit;
        }

        $path = base_path($document['file_path']);
        if (!is_file($path)) {
            $this->flash('danger', 'File is missing from storage.');
            $this->redirect('/documents');
        }

        header('Content-Type: ' . ($document['mime_type'] ?: 'application/octet-stream'));
        header('Content-Disposition: attachment; filename="' . basename($document['file_name']) . '"');
        header('Content-Length: ' . filesize($path));
        readfile($path);
        exit;
    }

    public function delete(): void
    {
        Auth::requireLogin();
        if (in_array(current_role(),['driver','carrier'],true)) { http_response_code(403); require app_path('Views/errors/403.php'); exit; }
        Csrf::verify();
        $document = $this->documents->delete((int) ($_POST['id'] ?? 0));
        if ($document) {
            $path = base_path($document['file_path']);
            if (is_file($path)) {
                unlink($path);
            }
        }
        log_activity('document_deleted', 'Deleted a document');
        $this->flash('success', 'Document deleted successfully.');
        $this->redirect('/documents');
    }
}
