<?php

namespace App\Repositories;

use App\Models\JobExperience;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

class JobExperienceRepository
{
    public function getAllForUser(int $userId, array $filters = []): LengthAwarePaginator
    {
        $query = JobExperience::where('user_id', $userId)
            ->with('user')
            ->latest();

        // Apply filters
        if (isset($filters['work_status'])) {
            $query->where('work_status', $filters['work_status']);
        }

        if (isset($filters['is_published'])) {
            $query->where('is_published', $filters['is_published']);
        }

        if (isset($filters['search'])) {
            $query->where(function ($q) use ($filters) {
                $q->where('job_title', 'like', "%{$filters['search']}%")
                  ->orWhere('company_name', 'like', "%{$filters['search']}%");
            });
        }

        return $query->paginate(10);
    }

    public function findById(int $id): ?JobExperience
    {
        return JobExperience::with('user')->find($id);
    }

    public function findByIdForUser(int $id, int $userId): ?JobExperience
    {
        return JobExperience::where('user_id', $userId)
            ->with('user')
            ->find($id);
    }

    public function getActiveJobForUser(int $userId): ?JobExperience
    {
        return JobExperience::where('user_id', $userId)
            ->where('published', true)
            ->with('user')
            ->latest()
            ->first();
    }

    public function create(array $data): JobExperience
    {
        return DB::transaction(function () use ($data) {
            $jobExperience = JobExperience::create($data);

            // If this is a current job and user doesn't have an active job, set it as active
            if ($data['still_employed'] && !$this->userHasActiveJob($data['user_id'])) {
                $this->setAsActive($jobExperience);
            }

            return $jobExperience;
        });
    }

    public function update(JobExperience $jobExperience, array $data): JobExperience
    {
        return DB::transaction(function () use ($jobExperience, $data) {
            $jobExperience->update($data);

            // If updating to current employment and it's not active, set as active
            if (isset($data['still_employed']) && $data['still_employed'] && !$jobExperience->still_employed) {
                $this->setAsActive($jobExperience);
            }

            return $jobExperience->fresh();
        });
    }

    public function delete(JobExperience $jobExperience): bool
    {
        return DB::transaction(function () use ($jobExperience) {
            $userId = $jobExperience->user_id;
            $wasActive = $jobExperience->still_employed;

            $result = $jobExperience->delete();

            // If we deleted the active job, set the most recent current job as active
            if ($wasActive) {
                $this->setNewActiveJob($userId);
            }

            return $result;
        });
    }

    public function setAsActive(JobExperience $jobExperience): void
    {
        DB::transaction(function () use ($jobExperience) {
            // Deactivate all other jobs for this user
            JobExperience::where('user_id', $jobExperience->user_id)
                ->where('id', '!=', $jobExperience->id)
                ->update(['still_employed' => false]);

            $jobExperience->update(['still_employed' => true]);
        });
    }

    public function publish(JobExperience $jobExperience): void
    {
        $jobExperience->update([
            'is_published' => true,
            'published_at' => now(),
        ]);
    }

    public function unpublish(JobExperience $jobExperience): void
    {
        $jobExperience->update([
            'is_published' => false,
            'published_at' => null,
        ]);
    }

    public function userHasActiveJob(int $userId): bool
    {
        return JobExperience::where('user_id', $userId)
            ->where('still_employed', true)
            ->exists();
    }

    public function getPublishedJobs(array $filters = []): LengthAwarePaginator
    {
        $query = JobExperience::where('is_published', true)
            ->with('user')
            ->latest();

        if (isset($filters['company_name'])) {
            $query->where('company_name', 'like', "%{$filters['company_name']}%");
        }

        if (isset($filters['job_title'])) {
            $query->where('job_title', 'like', "%{$filters['job_title']}%");
        }

        if (isset($filters['location'])) {
            $query->where('location', 'like', "%{$filters['location']}%");
        }

        return $query->paginate(12);
    }

    private function setNewActiveJob(int $userId): void
    {
        $newActiveJob = JobExperience::where('user_id', $userId)
            ->where('still_employed', true)
            ->latest()
            ->first();

        if ($newActiveJob) {
            $this->setAsActive($newActiveJob);
        }
    }
}
