<?php

namespace App\Http\Controllers;

use App\Models\RateMyPay;
use App\Models\PostComment;
use App\Models\JobExperience;
use App\Repositories\RateMyPayRepository;
use App\Services\SalaryMarketComparisonService;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class RateMyPayController extends Controller
{


    public function __construct(
        private RateMyPayRepository $rateMyPayRepository
    ) {}

    public function index(Request $request): View
    {
        $filters = $request->only(['search']);
        $posts = $this->rateMyPayRepository->getAllPosts($filters);
        
        return view('rate-my-pay.index', compact('posts'));
    }

    public function create(JobExperience $jobExperience): View
    {   
        return view('rate-my-pay.create', compact('jobExperience'));
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'job_experience_id' => 'required|exists:job_experiences,id',
            'content' => 'required|string|min:10|max:1000',
            'is_anonymous' => 'boolean',
            'payslip' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:5120',
            'community_ids' => 'nullable|array',
            'community_ids.*' => 'exists:communities,id',
        ]);

        $validated['user_id'] = auth()->id();
        $validated['is_anonymous'] = $request->has('is_anonymous');


        try {
            $post = $this->rateMyPayRepository->createPost($validated);

            // Attach communities if provided
            if ($request->has('community_ids') && !empty($request->community_ids)) {
                $this->rateMyPayRepository->addPostToCommunities($post, $request->community_ids);
            }
            
            // return redirect()->route('dashboard.index', $post)
            //     ->with('success', 'Your pay has been shared successfully!');
            return redirect()->back()
                ->with('success', 'Your post has been shared successfully!');
                
        } catch (\Exception $e) {
            return back()->withErrors(['error' => 'Failed to share your post: ' . $e->getMessage()])
                        ->withInput();
        }
    }


    public function show(RateMyPay $rateMyPay, SalaryMarketComparisonService $service)
    {
        $post = $this->rateMyPayRepository->findById($rateMyPay->id);
        $userRating = $this->rateMyPayRepository->getUserRating($rateMyPay, auth()->id());
        $canRate = $this->rateMyPayRepository->canUserRate($rateMyPay, auth()->id());

        $job = $rateMyPay->jobExperience;

        $marketComparison = null;
        $chart = null;

        if ($job) {
            $payload = [
                'job_title' => $job->job_title,
                'level' => $job->level,
                'experience' => (int) ($job->years_of_experience ?? 0),
                'location' => [
                    'country' => $job->location ?? $job->country,
                    'state' => $job->state,
                    'city' => $job->city,
                ],
                'annual_base_salary' => $job->annual_base_salary,
                'company' => [
                    'size' => $job->company_size,
                    'industry' => $job->industry,
                ]
            ];

            $marketComparison = $service->compare($payload);

            if (
                is_array($marketComparison) &&
                isset($marketComparison['percentiles'], $marketComparison['market_comparison'])
            ) {
                $values = [
                    'Lower Pay' => (int) $marketComparison['percentiles']['p25'],
                    'Average' => (int) $marketComparison['percentiles']['p50'],
                    'Your Pay' => (int) $job->total_compensation,
                    'Above Pay' => (int) $marketComparison['percentiles']['p75'],
                    'Top Pay' => (int) $marketComparison['percentiles']['p90'],
                ];
                asort($values);

                $chart = [
                    'values' => $values,
                    'max' => max($values),
                    'currency' => $marketComparison['currency'],
                ];
            }
        }

        return view(
            'rate-my-pay.show',
            compact('post', 'userRating', 'canRate', 'marketComparison', 'chart', 'job')
        );
    }



    public function destroy(RateMyPay $rateMyPay): RedirectResponse
    {
        try {
            $this->rateMyPayRepository->deletePost($rateMyPay);
            
            return redirect()->route('rate-my-pay.index')
                ->with('success', 'Post deleted successfully!');
                
        } catch (\Exception $e) {
            return back()->withErrors(['error' => 'Failed to delete post: ' . $e->getMessage()]);
        }
    }

    // public function rate(Request $request, RateMyPay $rateMyPay): RedirectResponse
    // {
    //     $validated = $request->validate([
    //         'rating' => 'required|integer|min:1|max:5',
    //         'salary' => 'nullable|numeric|min:0',
    //     ]);

    //     $validated['user_id'] = auth()->id();

    //     try {
    //         $this->rateMyPayRepository->addRating($rateMyPay, $validated);
            
    //         return back()->with('success', 'Rating submitted successfully!');
            
    //     } catch (\Exception $e) {
    //         return back()->withErrors(['error' => 'Failed to submit rating: ' . $e->getMessage()]);
    //     }
    // }

    public function rate(Request $request, RateMyPay $rateMyPay)
    {
        $validated = $request->validate([
            'rating'  => 'required|integer|min:1|max:5',
            'content' => 'nullable|string|min:3|max:500',
        ]);

        try {
            DB::beginTransaction();

            // Add/Update Rating
            $this->rateMyPayRepository->addRating($rateMyPay, [
                'user_id' => auth()->id(),
                'rating'  => $validated['rating'],
            ]);

            // Add Comment if content is provided
            $newComment = null;
            if ($request->filled('content')) {
                $newComment = $this->rateMyPayRepository->addComment($rateMyPay, [
                    'user_id' => auth()->id(),
                    'content' => $validated['content'],
                ]);
            }

            DB::commit();
            
            $rateMyPay->refresh();

            return response()->json([
                'status'         => true,
                'average_rating' => (float)$rateMyPay->average_rating,
                'ratings_count'  => $rateMyPay->ratings_count,
                'comments_count' => $rateMyPay->comments_count,
                'new_comment'    => $newComment ? [
                    'content'     => $newComment->content,
                    'author_name' => auth()->user()->name,
                    'created_at'  => 'Just now',
                    'rating'      => $validated['rating']
                ] : null,
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['status' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function removeRating(RateMyPay $rateMyPay): RedirectResponse
    {
        try {
            $this->rateMyPayRepository->removeRating($rateMyPay, auth()->id());
            
            return back()->with('success', 'Rating removed successfully!');
            
        } catch (\Exception $e) {
            return back()->withErrors(['error' => 'Failed to remove rating: ' . $e->getMessage()]);
        }
    }

    public function storeComment(Request $request, RateMyPay $rateMyPay)
    {
        $validated = $request->validate([
            'content' => 'required|string|min:1|max:500',
            'parent_id' => 'nullable|exists:post_comments,id',
        ]);

        $validated['user_id'] = auth()->id();

        try {
            $newComment = $this->rateMyPayRepository->addComment($rateMyPay, $validated);
            $commentData = $newComment->toArray();
            $commentData['author_name'] = auth()->user()->name;
            $commentData['user'] = auth()->user();
            // $newComment->load('user');
            $rateMyPay->refresh();
            
            return response()->json([
                'status' => true,
                'message' => 'Comment added successfully!',
                'comment' => $commentData,
                'comments_count' => $rateMyPay->comments_count,
            ], 201);
            
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Failed to add comment: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function updateComment(Request $request, PostComment $comment): RedirectResponse
    {
        $validated = $request->validate([
            'content' => 'required|string|min:1|max:500',
        ]);

        try {
            $this->rateMyPayRepository->updateComment($comment, $validated);
            
            return back()->with('success', 'Comment updated successfully!');
            
        } catch (\Exception $e) {
            return back()->withErrors(['error' => 'Failed to update comment: ' . $e->getMessage()]);
        }
    }

    public function destroyComment(PostComment $comment): RedirectResponse
    {
        try {
            $this->rateMyPayRepository->deleteComment($comment);
            
            return back()->with('success', 'Comment deleted successfully!');
            
        } catch (\Exception $e) {
            return back()->withErrors(['error' => 'Failed to delete comment: ' . $e->getMessage()]);
        }
    }

    public function like(RateMyPay $rateMyPay)
    {
        try {
            $liked = $this->rateMyPayRepository->toggleLike($rateMyPay, auth()->id());

            return response()->json([
                'status' => true,
                'message' => 'Like updated!',
                'liked' => $liked,
                'likes_count' => $rateMyPay->likes_count,
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Failed to toggle like: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function likeComment(PostComment $comment)
    {
        try {
            $liked = $this->rateMyPayRepository->toggleCommentLike($comment, auth()->id());
            
            // Refresh the comment to get the latest likes_count
            $comment->refresh(); 

            return response()->json([
                'status' => true,
                'message' => 'Comment like updated!',
                'liked' => $liked,
                'likes_count' => $comment->likes_count,
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Failed to toggle comment like: ' . $e->getMessage(),
            ], 500);
        }
    }
}