<?php

namespace App\Http\Controllers;

use App\Http\Traits\ResponseTrait;
use App\Http\Requests\StoreJobApplicationRequest;
use App\Http\Requests\ScheduleInterviewRequest;
use App\Models\Application;
use App\Models\Interview;
use App\Models\JobPost;
use App\Models\Notification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class JobApplicationController extends Controller
{
    use ResponseTrait;

    /**
     * Submit job application
     */
    public function apply(StoreJobApplicationRequest $request)
    {
        try {
            $user = $request->user();
            $jobPost = JobPost::findOrFail($request->job_post_id);

            // Handle resume upload
            $resumeFile = $request->file('resume');
            $resumeFilename = Str::uuid() . '.' . $resumeFile->getClientOriginalExtension();
            $resumePath = $resumeFile->storeAs('', $resumeFilename, 'resumes');
            $resumeUrl = Storage::disk('resumes')->url($resumePath);

            // Create application
            $application = Application::create([
                'job_post_id' => $request->job_post_id,
                'researcher_id' => $user->id,
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'email' => $request->email,
                'phone' => $request->phone,
                'resume_path' => $resumePath,
                'resume_url' => $resumeUrl,
                'cover_letter' => $request->cover_letter,
                'experience_level' => $request->experience_level,
                'available_date' => $request->available_date,
                'notice_period' => $request->notice_period,
                'salary_expectation' => $request->salary_expectation,
                'remote_interested' => $request->remote_interested ?? false,
                'additional_answers' => $request->additional_answers,
                'consent_data' => $request->consent_data,
                'consent_marketing' => $request->consent_marketing ?? false,
                'status' => 'applied',
            ]);

            // Send notification to recruiter
            if ($jobPost->recruiter && $jobPost->recruiter->user) {
                Notification::create([
                    'user_id' => $jobPost->recruiter->user->id,
                    'type' => 'job_application',
                    'title' => 'New Job Application',
                    'message' => "{$request->first_name} {$request->last_name} applied for {$jobPost->title}",
                    'data' => [
                        'url' => "/job-posts/{$jobPost->id}/applicants",
                        'action' => 'view_applicants',
                        'application_id' => $application->id,
                    ],
                ]);
            }

            return $this->successResponse([
                'id' => $application->id,
                'job_post_id' => $application->job_post_id,
                'application_id' => $application->id,
            ], 'Job application submitted successfully');

        } catch (\Exception $e) {
            return $this->errorResponse('Failed to submit application: ' . $e->getMessage());
        }
    }

    /**
     * Get applicants for a job posting
     */
    public function getApplicants(Request $request, $id)
    {
        $user = $request->user();
        $jobPost = JobPost::findOrFail($id);

        // Verify user is the recruiter who owns this job post
        if ($jobPost->recruiter_id && $user->recruiterProfile && $jobPost->recruiter_id !== $user->recruiterProfile->id) {
            return response()->json([
                'code' => 403,
                'error' => true,
                'status' => 'error',
                'message' => 'Unauthorized to view applicants for this job post'
            ], 403);
        }

        $perPage = $request->input('limit', 20);
        $perPage = min($perPage, 100);

        $query = Application::where('job_post_id', $id)
            ->with(['researcher'])
            ->orderBy('created_at', 'desc');

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

        // Search by name/email
        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('first_name', 'like', "%{$search}%")
                  ->orWhere('last_name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        $applications = $query->paginate($perPage);

        // Format response
        $formattedApplications = $applications->map(function($application) {
            $researcher = $application->researcher;
            $researcherProfile = $researcher->researcherProfile ?? null;
            
            return [
                'id' => $application->id,
                'name' => trim("{$application->first_name} {$application->last_name}"),
                'email' => $application->email,
                'phone' => $application->phone,
                'location' => $researcherProfile->location ?? null,
                'experience_level' => $application->experience_level,
                'status' => $application->status,
                'applied_at' => $application->created_at->toISOString(),
                'cover_letter' => $application->cover_letter,
                'salary_expectation' => $application->salary_expectation,
                'skills' => $researcherProfile->skills ?? [],
                'profile_photo' => $researcher->profile_photo,
                'resume_url' => $application->resume_url,
            ];
        });

        return $this->paginatedResponse(
            $applications->setCollection($formattedApplications),
            'Applicants retrieved successfully'
        );
    }

    /**
     * Update application status
     */
    public function updateStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|in:applied,reviewing,shortlisted,rejected,hired',
        ]);

        $user = $request->user();
        $application = Application::with('jobPost')->findOrFail($id);

        // Verify user is the recruiter who owns this job post
        if ($application->jobPost->recruiter_id && $user->recruiterProfile && 
            $application->jobPost->recruiter_id !== $user->recruiterProfile->id) {
            return response()->json([
                'code' => 403,
                'error' => true,
                'status' => 'error',
                'message' => 'Unauthorized to update this application'
            ], 403);
        }

        $application->update(['status' => $request->status]);

        // Send notification to applicant
        if ($application->researcher) {
            Notification::create([
                'user_id' => $application->researcher_id,
                'type' => 'job_application',
                'title' => 'Application Status Updated',
                'message' => "Your application for {$application->jobPost->title} has been updated to {$request->status}",
                'data' => [
                    'url' => "/job-applications/{$application->id}",
                    'action' => 'view_application',
                ],
            ]);
        }

        return response()->json([
            'code' => 200,
            'error' => false,
            'status' => 'success',
            'message' => 'Application status updated successfully'
        ], 200);
    }

    /**
     * Download applicant resume
     */
    public function getResume(Request $request, $id)
    {
        $user = $request->user();
        $application = Application::with('jobPost')->findOrFail($id);

        // Verify user has permission (recruiter who owns the job post or the applicant)
        $canView = false;
        if ($application->jobPost->recruiter_id && $user->recruiterProfile && 
            $application->jobPost->recruiter_id === $user->recruiterProfile->id) {
            $canView = true;
        }
        if ($application->researcher_id === $user->id) {
            $canView = true;
        }

        if (!$canView) {
            return response()->json([
                'code' => 403,
                'error' => true,
                'status' => 'error',
                'message' => 'Unauthorized to view this resume'
            ], 403);
        }

        if (!$application->resume_path) {
            return $this->notFoundResponse();
        }

        $filePath = Storage::disk('resumes')->path($application->resume_path);
        
        if (!file_exists($filePath)) {
            return $this->notFoundResponse();
        }

        return response()->download($filePath, $application->resume_path);
    }

    /**
     * Schedule interview
     */
    public function scheduleInterview(ScheduleInterviewRequest $request, $id)
    {
        $user = $request->user();
        $jobPost = JobPost::findOrFail($id);

        // Verify user is the recruiter who owns this job post
        if ($jobPost->recruiter_id && $user->recruiterProfile && 
            $jobPost->recruiter_id !== $user->recruiterProfile->id) {
            return response()->json([
                'code' => 403,
                'error' => true,
                'status' => 'error',
                'message' => 'Unauthorized to schedule interviews for this job post'
            ], 403);
        }

        $application = Application::findOrFail($request->application_id);

        // Verify application belongs to this job post
        if ($application->job_post_id != $id) {
            return response()->json([
                'code' => 422,
                'error' => true,
                'status' => 'error',
                'message' => 'Application does not belong to this job post'
            ], 422);
        }

        try {
            // Combine date and time
            $interviewDateTime = \Carbon\Carbon::parse($request->interview_date)
                ->setTimeFromTimeString($request->interview_time);

            $interview = Interview::create([
                'application_id' => $application->id,
                'job_post_id' => $id,
                'recruiter_id' => $jobPost->recruiter_id,
                'applicant_id' => $application->researcher_id,
                'interview_date' => $interviewDateTime,
                'interview_time' => $request->interview_time,
                'location' => $request->location,
                'interview_type' => $request->interview_type,
                'notes' => $request->notes,
                'status' => 'scheduled',
            ]);

            // Send notification to applicant
            if ($application->researcher) {
                Notification::create([
                    'user_id' => $application->researcher_id,
                    'type' => 'job_application',
                    'title' => 'Interview Scheduled',
                    'message' => "An interview has been scheduled for your application to {$jobPost->title}",
                    'data' => [
                        'url' => "/interviews/{$interview->id}",
                        'action' => 'view_interview',
                        'interview_id' => $interview->id,
                    ],
                ]);
            }

            return $this->successResponse([
                'interview_id' => $interview->id,
            ], 'Interview scheduled successfully');

        } catch (\Exception $e) {
            return $this->errorResponse('Failed to schedule interview: ' . $e->getMessage());
        }
    }
}
