<?hh // strict

namespace App\Controllers;

use App\Models\Job;
use App\Services\JobService;
use PDO;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class JobController
{
    private JobService $jobService;
    
    public function __construct()
    {
        // In a real application, this would be injected via DI container
        $this->jobService = new JobService($this->getDbConnection());
    }

    public function listJobs(Request $request, Response $response): Response
    {
        // Extract filters from query parameters
        $params = $request->getQueryParams();
        $filters = [];
        
        if (isset($params['location'])) {
            $filters['location'] = $params['location'];
        }
        
        if (isset($params['keywords'])) {
            $filters['keywords'] = $params['keywords'];
        }
        
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        
        $jobs = $this->jobService->getAllJobs($tenant, $filters);
        
        $jobsArray = [];
        foreach ($jobs as $job) {
            $jobsArray[] = [
                'id' => $job->getId(),
                'title' => $job->getTitle(),
                'description' => $job->getDescription(),
                'location' => $job->getLocation(),
                'employment_type' => $job->getEmploymentType(),
                'created_at' => $job->getCreatedAt()->format('Y-m-d H:i:s')
            ];
        }
        
        $response->getBody()->write(json_encode($jobsArray));
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function getJob(Request $request, Response $response, array $args): Response
    {
        $jobId = (int)$args['id'];
        
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        
        $job = $this->jobService->getJobById($jobId, $tenant);
        
        if (!$job) {
            $response = $response->withStatus(404);
            $response->getBody()->write(json_encode(['error' => 'Job not found']));
            return $response->withHeader('Content-Type', 'application/json');
        }
        
        $jobData = [
            'id' => $job->getId(),
            'title' => $job->getTitle(),
            'description' => $job->getDescription(),
            'location' => $job->getLocation(),
            'employment_type' => $job->getEmploymentType(),
            'created_at' => $job->getCreatedAt()->format('Y-m-d H:i:s'),
            'updated_at' => $job->getUpdatedAt()->format('Y-m-d H:i:s')
        ];
        
        $response->getBody()->write(json_encode($jobData));
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function myJobs(Request $request, Response $response): Response
    {
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        
        // For job providers, get jobs they've posted
        // This would typically involve checking user permissions
        // For now, just return all jobs for the tenant
        
        $jobs = $this->jobService->getAllJobs($tenant);
        
        $jobsArray = [];
        foreach ($jobs as $job) {
            $jobsArray[] = [
                'id' => $job->getId(),
                'title' => $job->getTitle(),
                'description' => $job->getDescription(),
                'location' => $job->getLocation(),
                'employment_type' => $job->getEmploymentType(),
                'created_at' => $job->getCreatedAt()->format('Y-m-d H:i:s')
            ];
        }
        
        $response->getBody()->write(json_encode($jobsArray));
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function createJob(Request $request, Response $response): Response
    {
        $params = $request->getParsedBody();
        
        // Validate required fields
        $required = ['title', 'description', 'location', 'employment_type'];
        foreach ($required as $field) {
            if (empty($params[$field])) {
                $response = $response->withStatus(400);
                $response->getBody()->write(json_encode(['error' => "Missing required field: {$field}"]));
                return $response->withHeader('Content-Type', 'application/json');
            }
        }
        
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        $tenantId = $tenant ? $tenant->getId() : 'default';
        
        // Create job
        $job = new Job(
            id: 0, // Will be set by database
            title: $params['title'],
            description: $params['description'],
            location: $params['location'],
            employmentType: $params['employment_type'],
            tenantId: $tenantId
        );
        
        $result = $this->jobService->createJob($job);
        
        if ($result) {
            $response->getBody()->write(json_encode(['message' => 'Job created successfully']));
            return $response->withHeader('Content-Type', 'application/json')->withStatus(201);
        } else {
            $response = $response->withStatus(500);
            $response->getBody()->write(json_encode(['error' => 'Failed to create job']));
            return $response->withHeader('Content-Type', 'application/json');
        }
    }

    public function updateJob(Request $request, Response $response, array $args): Response
    {
        $jobId = (int)$args['id'];
        $params = $request->getParsedBody();
        
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        
        // First get the existing job to ensure it belongs to this tenant
        $existingJob = $this->jobService->getJobById($jobId, $tenant);
        
        if (!$existingJob) {
            $response = $response->withStatus(404);
            $response->getBody()->write(json_encode(['error' => 'Job not found or does not belong to your tenant']));
            return $response->withHeader('Content-Type', 'application/json');
        }
        
        // Update the job with new data
        $existingJob->setTitle($params['title'] ?? $existingJob->getTitle());
        $existingJob->setDescription($params['description'] ?? $existingJob->getDescription());
        $existingJob->setLocation($params['location'] ?? $existingJob->getLocation());
        $existingJob->setEmploymentType($params['employment_type'] ?? $existingJob->getEmploymentType());
        
        $result = $this->jobService->updateJob($existingJob);
        
        if ($result) {
            $response->getBody()->write(json_encode(['message' => 'Job updated successfully']));
            return $response->withHeader('Content-Type', 'application/json');
        } else {
            $response = $response->withStatus(500);
            $response->getBody()->write(json_encode(['error' => 'Failed to update job']));
            return $response->withHeader('Content-Type', 'application/json');
        }
    }

    public function deleteJob(Request $request, Response $response, array $args): Response
    {
        $jobId = (int)$args['id'];
        
        // Get tenant from request attribute (set by middleware)
        $tenant = $request->getAttribute('tenant');
        
        $result = $this->jobService->deleteJob($jobId, $tenant);
        
        if ($result) {
            $response->getBody()->write(json_encode(['message' => 'Job deleted successfully']));
            return $response->withHeader('Content-Type', 'application/json');
        } else {
            $response = $response->withStatus(404);
            $response->getBody()->write(json_encode(['error' => 'Job not found or does not belong to your tenant']));
            return $response->withHeader('Content-Type', 'application/json');
        }
    }
    
    private function getDbConnection(): PDO
    {
        // In a real application, this would be configured properly
        $host = $_ENV['DB_HOST'] ?? 'localhost';
        $dbname = $_ENV['DB_NAME'] ?? 'moh';
        $username = $_ENV['DB_USER'] ?? 'moh_user';
        $password = $_ENV['DB_PASS'] ?? 'moh_password';
        $port = $_ENV['DB_PORT'] ?? '5432';
        
        $dsn = "pgsql:host={$host};port={$port};dbname={$dbname};";
        return new PDO($dsn, $username, $password, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }
}