<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Illuminate\Http\JsonResponse;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Storage;
use DB;
use App\Traits\DeleteModelTrait; 

class PostController extends Controller
{
    use DeleteModelTrait;
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        // Start a query on the Post model and eager load categories and tags.
        $query = Post::with(['categories']);

        // If a category slug is provided (e.g., ?category=design), filter posts by that category.
        if ($request->has('category')) {
            $categorySlug = $request->input('category');
            $query->whereHas('categories', function ($q) use ($categorySlug) {
                $q->where('slug', $categorySlug);
            });
        }

        // Add search functionality
        if ($request->has('search')) {
            $searchTerm = $request->input('search');
            $query->where(function ($q) use ($searchTerm) {
                $q->where('title', 'like', '%' . $searchTerm . '%')
                ->orWhere('tags', 'like', '%' . $searchTerm . '%')
                ->orWhere('slug', 'like', '%' . $searchTerm . '%')
                ->orWhereHas('categories', function ($q2) use ($searchTerm) {
                    $q2->where('title', 'like', '%' . $searchTerm . '%');
                });
            });
        }

        // Get posts ordered by latest and paginate them.
        $posts = $query->latest()->paginate(8)->through(function ($post) {
            return [
                'title'      => $post->title,
                'slug'       => $post->slug,
                'created_at' => $post->created_at->format('Y-m-d H:i:s'),
                'photo'      => $post->photo,
                'description'=> $post->description,
                // Display the first category title or fallback text.
                'category'   => $post->categories->first()?->title ?? 'No Category',
            ];
        });

        return Inertia::render('News', [
            'posts' => $posts,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
        try{
            DB::beginTransaction();
            //validating form data
            $validatedData = $request->validate([
                'title' => 'required|min:3|max:250', 
                'photo' => 'required',
                'description' => 'required',
                'status' => 'required|boolean',
                'tags' => 'required|string',
                'categories' => 'required|array',
                'categories.*' => 'required|integer|exists:categories,id',
                
            
            ]);

            if (!empty($validatedData['tags'])) {
                $validatedData['tags'] = array_map('trim', explode(',', $validatedData['tags']));
            } else {
                $validatedData['tags'] = [];
            }

            $post = new Post;
            $post->title = $validatedData['title'];
            $post->slug = tap(Str::slug($validatedData['title']), function (&$slug) use ($validatedData){
                $counter = 1;
                while (\App\Models\Post::withTrashed()->where('slug', $slug)->exists()) {
                    $slug = Str::slug($validatedData['title']) . '-' . $counter++;
                }
            });
            $post->description = $validatedData['description'];
            $post->status = $validatedData['status'];
            $post->photo = $validatedData['photo'];
            $post->tags = $validatedData['tags'];
            $post->save();
            $categoryIds = $validatedData['categories'];
            $post->categories()->sync($categoryIds);

            DB::commit();
            return to_route('admin.posts')->with('success', [
                'message' => 'News created successfully',
                'check' => false
            ]);
        } catch (ValidationException $e){
            DB::rollBack();
            return redirect()->back()
                ->withErrors($e->errors()) 
                ->withInput(); 
                
        } catch(\Exception $e) {
            DB::rollBack();
            return Redirect::back()->with('error', [
                'message' => 'Error: '.$e->getMessage(),
                'check' => $e->getMessage()
            ]);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show($slug)
    {
        $post = Post::with(['categories'])
        ->where('slug', $slug)
        ->firstOrFail();
        
        return Inertia::render('NewsDetail', [
            'post' => [
                'title' => $post->title,
                'slug' => $post->slug,
                'created_at' => $post->created_at->format('Y-m-d H:i:s'),
                'photo' => $post->photo,
                'tags' => $post->tags,
                'description' => $post->description,
                'categories' => $post->categories->map(function ($category) {
                    return [
                        'title' => $category->title,  
                        'slug' => $category->slug,
                    ];
                }),
            ]
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
{
    $post = Post::with(['categories'])->findOrFail($id);
    $postArray = $post->toArray();
    $postArray['categories'] = collect($postArray['categories'])->pluck('id')->toArray();

    if (isset($postArray['tags']) && is_array($postArray['tags'])) {
        $postArray['tags'] = implode(',', $postArray['tags']);
    }
    
    return response()->json($postArray);
}


    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        try {
            DB::beginTransaction();
            $validatedData = $request->validate([
                'title'       => 'required|min:3|max:250', 
                'photo'       => 'required',
                'description' => 'required',
                'status'      => 'required',
                'tags'        => 'required|string',
                'categories'  => 'required|array',
                'categories.*'=> 'required|integer|exists:categories,id',
            ]);

            if (!empty($validatedData['tags'])) {
                $validatedData['tags'] = array_map('trim', explode(',', $validatedData['tags']));
            } else {
                $validatedData['tags'] = [];
            }

            // Retrieve the post or fail.
            $post = Post::findOrFail($id);

            // Update slug if title changed
            if ($post->title !== $validatedData['title']) {
                $post->slug = tap(Str::slug($validatedData['title']), function (&$slug) use ($validatedData, $post) {
                    $counter = 1;
                    while (Post::withTrashed()->where('slug', $slug)->where('id', '!=', $post->id)->exists()) {
                        $slug = Str::slug($validatedData['title']) . '-' . $counter++;
                    }
                });
            }

            // Update photo if provided and changed.
            if ($request->has('photo') && $request->input('photo') !== $post->photo) {
                $post->photo = $request->input('photo');
            }

            // Fill the post with validated data (this updates only the model's attributes)
            $post->fill($validatedData);
            if ($post->isDirty()){
                $post->save();
            }

            // Sync the many-to-many relationships for categories.
            $post->categories()->sync($validatedData['categories']);

            DB::commit();

            return Redirect::back()->with('success', [
                'message' => 'News updated successfully',
                'check'   => false
            ]);
        } catch (ValidationException $e) {
            DB::rollBack();
            return Redirect::back()->with('error', [
                'message' => 'Validation error: ' . $e->getMessage(),
                'check'   => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return Redirect::back()->with('error', [
                'message' => 'Error: ' . $e->getMessage(),
                'check'   => $e->getMessage()
            ]);
        }
    }


    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        return $this->deleteModel($id, new Post());
    }

    public function fetchPosts()
    {
        // Fetch all posts with their related models
        $posts = Post::with(['categories'])
            ->orderBy('created_at', 'desc')
            ->get();

        return Inertia::render('posts/Post', [
            'posts' => $posts->map(function ($post) {
                return [
                    'id' => $post->id,
                    'title' => $post->title,
                    'tags' => $post->tags,
                    'categories' => $post->categories->map(function ($category) {
                        return [
                            'id' => $category->id,
                            'title' => $category->title
                        ];
                    }),
                    'photo' => $post->photo,
                    'button' => $post->button,
                    'status' => $post->status,
                    'created_at' => $post->created_at,
                ];
            }),
        ]);
    }

    public function uploadImage(Request $request)
    {
        // Validate the image upload
        $request->validate([
            'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5048',
        ]);

         
        $path = $request->file('file')->store('posts/images', 'public');  
        $filename = basename($path); 

        return response()->json(['filename' => 'posts/images/' . $filename]); 
    }
}
