<?php

namespace App\Http\Controllers;

use App\Models\Job;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Notifications\GeneralNotification;
use App\Services\AdminNotificationService;

class JobController extends Controller
{
    /**
     * Create a new job posting
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'job_title' => 'required|string|max:255',
            'company_name' => 'required|string|max:255',
            'job_description' => 'required|string',
            'requirements' => 'nullable|string',
            'location' => 'nullable|string|max:255',
            'salary_range' => 'nullable|string|max:255',
            'job_type' => 'nullable|string|in:full-time,part-time,contract,remote',
            'experience_level' => 'nullable|string|in:entry,mid,senior',
            'application_deadline' => 'nullable|date'
        ]);

        $user = Auth::user();

        $job = new Job;
        $job->employer_id = $user->id;
        $job->job_title = $request->job_title;
        $job->company_name = $request->company_name;
        $job->job_description = $request->job_description;
        $job->requirements = $request->requirements;
        $job->location = $request->location;
        $job->salary_range = $request->salary_range;
        $job->job_type = $request->job_type ?? 'full-time';
        $job->experience_level = $request->experience_level ?? 'entry';
        $job->application_deadline = $request->application_deadline;
        $job->status = 'pending';
        $job->save();

        // Send admin notification
        AdminNotificationService::newJobPostingRequest($job);

        // Notify user
        $notification_details = [
            'title' => 'Job Posting Submitted',
            'content' => 'Your job posting for "' . $job->job_title . '" has been submitted and is pending admin approval.',
            'mail_content' => "Dear " . $user->name . ", <br/><br/> Your job posting for \"" . $job->job_title . "\" at " . $job->company_name . " has been submitted successfully. It is pending admin approval.<br/><br/>Thank you.",
            'url' => '/employer'
        ];
        $activity = (object)$notification_details;
        $user->notify(new GeneralNotification($activity));

        return response()->json([
            'status' => 'success',
            'message' => 'Job posting submitted successfully. It is pending admin approval.',
            'job' => $job->load('employer')
        ], 200);
    }

    /**
     * Get approved jobs for public viewing
     *
     * @return \Illuminate\Http\Response
     */
    public function getApprovedJobs()
    {
        $jobs = Job::where('status', 'approved')
            ->orderByDesc('created_at')
            ->with('employer')
            ->get();

        return response()->json([
            'status' => 'success',
            'jobs' => $jobs
        ], 200);
    }

    /**
     * Get pending jobs for admin
     *
     * @return \Illuminate\Http\Response
     */
    public function getPendingJobs()
    {
        $jobs = Job::where('status', 'pending')
            ->orderByDesc('created_at')
            ->with('employer')
            ->get();

        return response()->json([
            'status' => 'success',
            'jobs' => $jobs
        ], 200);
    }

    /**
     * Admin approve or reject job posting
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function approveJob(Request $request, $id)
    {
        $request->validate([
            'action' => 'required|in:approved,rejected',
            'admin_notes' => 'nullable|string'
        ]);

        $job = Job::find($id);
        if (!$job) {
            return response()->json([
                'status' => 'error',
                'message' => 'Job not found'
            ], 404);
        }

        if ($job->status !== 'pending') {
            return response()->json([
                'status' => 'error',
                'message' => 'Job has already been processed'
            ], 400);
        }

        $employer = $job->employer;

        $job->status = $request->action;
        $job->admin_notes = $request->admin_notes;
        $job->processed_at = now();
        $job->save();

        // Notify employer
        $notificationTitle = $request->action === 'approved' ? 'Job Posting Approved' : 'Job Posting Rejected';
        $notificationContent = $request->action === 'approved' 
            ? 'Your job posting for "' . $job->job_title . '" has been approved and is now live.'
            : 'Your job posting for "' . $job->job_title . '" has been rejected.';

        $notification_details = [
            'title' => $notificationTitle,
            'content' => $notificationContent,
            'mail_content' => "Dear " . $employer->name . ", <br/><br/> " . $notificationContent . "<br/><br/>" . ($request->admin_notes ? "Admin Notes: " . $request->admin_notes . "<br/><br/>" : "") . "Thank you.",
            'url' => '/employer'
        ];
        $activity = (object)$notification_details;
        $employer->notify(new GeneralNotification($activity));

        return response()->json([
            'status' => 'success',
            'message' => 'Job ' . $request->action . ' successfully',
            'job' => $job->load('employer')
        ], 200);
    }

    /**
     * Get user's job postings
     *
     * @return \Illuminate\Http\Response
     */
    public function getUserJobPostings()
    {
        $user = Auth::user();
        
        $jobs = Job::where('employer_id', $user->id)
            ->orderByDesc('created_at')
            ->with('employer')
            ->get();

        return response()->json([
            'status' => 'success',
            'jobs' => $jobs
        ], 200);
    }

    /**
     * Get specific user's job postings (for admin)
     *
     * @param  int  $userId
     * @return \Illuminate\Http\Response
     */
    public function getUserJobPostingsById($userId)
    {
        $jobs = Job::where('employer_id', $userId)
            ->orderByDesc('created_at')
            ->with('employer')
            ->get();

        return response()->json([
            'status' => 'success',
            'jobs' => $jobs
        ], 200);
    }

    /**
     * Admin: List all job postings with filtering
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function adminListJobs(Request $request)
    {
        $query = Job::with('employer', 'applications');

        // Filter by status
        if ($request->has('status') && $request->status !== '') {
            $query->where('status', $request->status);
        }

        // Filter by employer_id
        if ($request->has('employer_id') && $request->employer_id !== '') {
            $query->where('employer_id', $request->employer_id);
        }

        // Filter by job_type
        if ($request->has('job_type') && $request->job_type !== '') {
            $query->where('job_type', $request->job_type);
        }

        // Filter by experience_level
        if ($request->has('experience_level') && $request->experience_level !== '') {
            $query->where('experience_level', $request->experience_level);
        }

        // Search by job title or company name
        if ($request->has('search') && $request->search !== '') {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('job_title', 'like', "%{$search}%")
                  ->orWhere('company_name', 'like', "%{$search}%");
            });
        }

        // Sorting
        $sortBy = $request->get('sort_by', 'created_at');
        $sortOrder = $request->get('sort_order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        // Pagination
        $perPage = $request->get('per_page', 15);
        $jobs = $query->paginate($perPage);

        return response()->json([
            'status' => 'success',
            'jobs' => $jobs->items(),
            'pagination' => [
                'current_page' => $jobs->currentPage(),
                'last_page' => $jobs->lastPage(),
                'per_page' => $jobs->perPage(),
                'total' => $jobs->total(),
                'from' => $jobs->firstItem(),
                'to' => $jobs->lastItem(),
            ]
        ], 200);
    }

    /**
     * Admin: Get a specific job posting
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function adminShowJob($id)
    {
        $job = Job::with('employer', 'applications')->find($id);

        if (!$job) {
            return response()->json([
                'status' => 'error',
                'message' => 'Job posting not found'
            ], 404);
        }

        return response()->json([
            'status' => 'success',
            'job' => $job
        ], 200);
    }

    /**
     * Admin: Create a new job posting
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function adminCreateJob(Request $request)
    {
        $request->validate([
            'employer_id' => 'required|exists:users,id',
            'job_title' => 'required|string|max:255',
            'company_name' => 'required|string|max:255',
            'job_description' => 'required|string',
            'requirements' => 'nullable|string',
            'location' => 'nullable|string|max:255',
            'salary_range' => 'nullable|string|max:255',
            'job_type' => 'nullable|string|in:full-time,part-time,contract,remote',
            'experience_level' => 'nullable|string|in:entry,mid,senior',
            'application_deadline' => 'nullable|date',
            'status' => 'nullable|string|in:pending,approved,rejected'
        ]);

        $job = new Job;
        $job->employer_id = $request->employer_id;
        $job->job_title = $request->job_title;
        $job->company_name = $request->company_name;
        $job->job_description = $request->job_description;
        $job->requirements = $request->requirements;
        $job->location = $request->location;
        $job->salary_range = $request->salary_range;
        $job->job_type = $request->job_type ?? 'full-time';
        $job->experience_level = $request->experience_level ?? 'entry';
        $job->application_deadline = $request->application_deadline;
        $job->status = $request->status ?? 'approved'; // Admin can create approved jobs directly
        $job->admin_notes = $request->admin_notes;
        
        if ($job->status === 'approved' || $job->status === 'rejected') {
            $job->processed_at = now();
        }
        
        $job->save();

        $employer = $job->employer;

        // Notify employer if job is created as approved
        if ($job->status === 'approved') {
            $notification_details = [
                'title' => 'Job Posting Created',
                'content' => 'A job posting for "' . $job->job_title . '" has been created and approved by admin.',
                'mail_content' => "Dear " . $employer->name . ", <br/><br/> A job posting for \"" . $job->job_title . "\" at " . $job->company_name . " has been created and approved by admin.<br/><br/>Thank you.",
                'url' => '/employer'
            ];
            $activity = (object)$notification_details;
            $employer->notify(new GeneralNotification($activity));
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Job posting created successfully',
            'job' => $job->load('employer')
        ], 201);
    }

    /**
     * Admin: Update a job posting
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function adminUpdateJob(Request $request, $id)
    {
        $request->validate([
            'employer_id' => 'sometimes|exists:users,id',
            'job_title' => 'sometimes|string|max:255',
            'company_name' => 'sometimes|string|max:255',
            'job_description' => 'sometimes|string',
            'requirements' => 'nullable|string',
            'location' => 'nullable|string|max:255',
            'salary_range' => 'nullable|string|max:255',
            'job_type' => 'nullable|string|in:full-time,part-time,contract,remote',
            'experience_level' => 'nullable|string|in:entry,mid,senior',
            'application_deadline' => 'nullable|date',
            'status' => 'nullable|string|in:pending,approved,rejected',
            'admin_notes' => 'nullable|string'
        ]);

        $job = Job::find($id);
        if (!$job) {
            return response()->json([
                'status' => 'error',
                'message' => 'Job posting not found'
            ], 404);
        }

        $oldStatus = $job->status;
        $oldEmployerId = $job->employer_id;

        // Update fields
        if ($request->has('employer_id')) {
            $job->employer_id = $request->employer_id;
        }
        if ($request->has('job_title')) {
            $job->job_title = $request->job_title;
        }
        if ($request->has('company_name')) {
            $job->company_name = $request->company_name;
        }
        if ($request->has('job_description')) {
            $job->job_description = $request->job_description;
        }
        if ($request->has('requirements')) {
            $job->requirements = $request->requirements;
        }
        if ($request->has('location')) {
            $job->location = $request->location;
        }
        if ($request->has('salary_range')) {
            $job->salary_range = $request->salary_range;
        }
        if ($request->has('job_type')) {
            $job->job_type = $request->job_type;
        }
        if ($request->has('experience_level')) {
            $job->experience_level = $request->experience_level;
        }
        if ($request->has('application_deadline')) {
            $job->application_deadline = $request->application_deadline;
        }
        if ($request->has('status')) {
            $job->status = $request->status;
            if ($request->status === 'approved' || $request->status === 'rejected') {
                $job->processed_at = now();
            }
        }
        if ($request->has('admin_notes')) {
            $job->admin_notes = $request->admin_notes;
        }

        $job->save();

        $employer = $job->employer;

        // Notify employer if status changed
        if ($oldStatus !== $job->status) {
            $notificationTitle = $job->status === 'approved' ? 'Job Posting Approved' : ($job->status === 'rejected' ? 'Job Posting Rejected' : 'Job Posting Updated');
            $notificationContent = '';
            
            if ($job->status === 'approved') {
                $notificationContent = 'Your job posting for "' . $job->job_title . '" has been approved and is now live.';
            } elseif ($job->status === 'rejected') {
                $notificationContent = 'Your job posting for "' . $job->job_title . '" has been rejected.';
            } else {
                $notificationContent = 'Your job posting for "' . $job->job_title . '" has been updated by admin.';
            }

            $notification_details = [
                'title' => $notificationTitle,
                'content' => $notificationContent,
                'mail_content' => "Dear " . $employer->name . ", <br/><br/> " . $notificationContent . "<br/><br/>" . ($request->admin_notes ? "Admin Notes: " . $request->admin_notes . "<br/><br/>" : "") . "Thank you.",
                'url' => '/employer'
            ];
            $activity = (object)$notification_details;
            $employer->notify(new GeneralNotification($activity));
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Job posting updated successfully',
            'job' => $job->load('employer')
        ], 200);
    }

    /**
     * Admin: Delete a job posting
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function adminDeleteJob($id)
    {
        $job = Job::with('employer', 'applications')->find($id);

        if (!$job) {
            return response()->json([
                'status' => 'error',
                'message' => 'Job posting not found'
            ], 404);
        }

        $employer = $job->employer;
        $jobTitle = $job->job_title;

        // Check if there are applications
        if ($job->applications && $job->applications->count() > 0) {
            return response()->json([
                'status' => 'error',
                'message' => 'Cannot delete job posting with existing applications. Please reject it instead.',
                'applications_count' => $job->applications->count()
            ], 400);
        }

        $job->delete();

        // Notify employer
        $notification_details = [
            'title' => 'Job Posting Deleted',
            'content' => 'Your job posting for "' . $jobTitle . '" has been deleted by admin.',
            'mail_content' => "Dear " . $employer->name . ", <br/><br/> Your job posting for \"" . $jobTitle . "\" has been deleted by admin.<br/><br/>Thank you.",
            'url' => '/employer'
        ];
        $activity = (object)$notification_details;
        $employer->notify(new GeneralNotification($activity));

        return response()->json([
            'status' => 'success',
            'message' => 'Job posting deleted successfully'
        ], 200);
    }
}
