<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Post;
use App\Models\PostComment;
use App\Models\PostImage;
use App\Models\PostLike;
use App\Models\PostReport;
use App\Models\PostSave;
use App\Models\User;
use App\Services\ImageService;
use App\Services\OneSignalService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class PostController extends Controller
{
    public function __construct(
        private ImageService $imageService,
    ) {}

    public function index(Request $request): JsonResponse
    {
        $user = $request->user();

        $followingIds = $user->following()->pluck('users.id')->toArray();
        $followingIds[] = $user->id;

        $hasLikesTable = Schema::hasTable('post_likes');
        $hasCommentsTable = Schema::hasTable('post_comments');

        $query = Post::active()
            ->whereIn('user_id', $followingIds)
            ->with([
                'user:id,name,username,avatar,role',
                'images',
                'tags:id,name,username,avatar',
                'listing:id,title,price,pricing_type',
                'listing.images',
            ]);

        if ($hasCommentsTable) {
            $query->with(['comments' => fn($q) => $q->with('user:id,name,username,avatar')->latest()->limit(2)]);
        }

        $withCounts = [];
        if ($hasLikesTable) $withCounts[] = 'likes';
        if ($hasCommentsTable) $withCounts[] = 'comments';
        if (!empty($withCounts)) {
            $query->withCount($withCounts);
        }

        $posts = $query->latest()->paginate($request->get('per_page', 15));

        $likedPostIds = [];
        if ($hasLikesTable) {
            $likedPostIds = PostLike::where('user_id', $user->id)
                ->whereIn('post_id', $posts->pluck('id'))
                ->pluck('post_id')
                ->toArray();
        }

        $hasSavesTable = Schema::hasTable('post_saves');
        $savedPostIds = [];
        if ($hasSavesTable) {
            $savedPostIds = PostSave::where('user_id', $user->id)
                ->whereIn('post_id', $posts->pluck('id'))
                ->pluck('post_id')
                ->toArray();
        }

        $posts->getCollection()->transform(function ($post) use ($likedPostIds, $savedPostIds, $hasLikesTable, $hasCommentsTable) {
            if (!$hasLikesTable) $post->likes_count = 0;
            if (!$hasCommentsTable) $post->comments_count = 0;
            $post->is_liked = in_array($post->id, $likedPostIds);
            $post->is_saved = in_array($post->id, $savedPostIds);
            return $post;
        });

        return response()->json($posts);
    }

    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'content' => 'nullable|string|max:2000',
            'listing_id' => 'nullable|exists:listings,id',
            'images' => 'nullable|array|max:5',
            'images.*' => 'image|mimes:jpeg,png,jpg,webp|max:5120',
            'tagged_user_ids' => 'nullable|array|max:10',
            'tagged_user_ids.*' => 'exists:users,id',
        ]);

        if (!$request->content && !$request->hasFile('images') && !$request->listing_id) {
            return response()->json([
                'message' => 'Paylaşım için en az bir içerik, görsel veya ilan gereklidir.',
            ], 422);
        }

        $post = DB::transaction(function () use ($request) {
            $post = Post::create([
                'user_id' => $request->user()->id,
                'content' => $request->content,
                'listing_id' => $request->listing_id,
            ]);

            if ($request->hasFile('images')) {
                foreach ($request->file('images') as $index => $image) {
                    $path = $this->imageService->compress($image, 'posts', ImageService::PRESET_POST);
                    PostImage::create([
                        'post_id' => $post->id,
                        'image_path' => $path,
                        'sort_order' => $index,
                    ]);
                }
            }

            if ($request->tagged_user_ids) {
                $tagData = collect($request->tagged_user_ids)
                    ->unique()
                    ->filter(fn($id) => $id != $request->user()->id)
                    ->mapWithKeys(fn($id) => [$id => []]);

                $post->tags()->attach($tagData);
            }

            return $post;
        });

        $post->load(['user:id,name,username,avatar,role', 'images', 'tags:id,name,username,avatar', 'listing:id,title,price,pricing_type', 'listing.images']);
        $post->loadCount(['likes', 'comments']);
        $post->is_liked = false;

        if ($request->tagged_user_ids) {
            try {
                $query = User::whereIn('id', $request->tagged_user_ids)
                    ->where('id', '!=', $request->user()->id);

                if (\Schema::hasColumn('users', 'notifications_enabled')) {
                    $query->where('notifications_enabled', true);
                }

                $taggedUsers = $query->pluck('id')->toArray();

                if (!empty($taggedUsers)) {
                    app(OneSignalService::class)->sendToUsers(
                        $taggedUsers,
                        'Etiketlendiniz',
                        "{$request->user()->name} sizi bir paylaşımda etiketledi.",
                        [
                            'type' => 'post_tag',
                            'post_id' => $post->id,
                            'user_id' => $request->user()->id,
                        ],
                    );
                }
            } catch (\Exception $e) {
                \Log::warning('Post bildirim gönderilemedi: ' . $e->getMessage());
            }
        }

        return response()->json([
            'message' => 'Paylaşım oluşturuldu.',
            'post' => $post,
        ], 201);
    }

    public function show(Post $post, Request $request): JsonResponse
    {
        if ($post->status !== 'active') {
            return response()->json(['message' => 'Paylaşım bulunamadı.'], 404);
        }

        $hasLikesTable = Schema::hasTable('post_likes');
        $hasCommentsTable = Schema::hasTable('post_comments');

        $relations = [
            'user:id,name,username,avatar,role',
            'images',
            'tags:id,name,username,avatar',
            'listing:id,title,price,pricing_type',
            'listing.images',
        ];
        if ($hasCommentsTable) {
            $relations['comments'] = fn($q) => $q->with('user:id,name,username,avatar')->latest()->limit(2);
        }
        $post->load($relations);

        $counts = [];
        if ($hasLikesTable) $counts[] = 'likes';
        if ($hasCommentsTable) $counts[] = 'comments';
        if (!empty($counts)) $post->loadCount($counts);

        if (!$hasLikesTable) $post->likes_count = 0;
        if (!$hasCommentsTable) $post->comments_count = 0;
        $post->is_liked = ($request->user() && $hasLikesTable) ? $post->isLikedBy($request->user()) : false;
        $post->is_saved = ($request->user()) ? $post->isSavedBy($request->user()) : false;

        return response()->json(['post' => $post]);
    }

    public function update(Post $post, Request $request): JsonResponse
    {
        if ($post->user_id !== $request->user()->id) {
            return response()->json(['message' => 'Bu paylaşımı düzenleme yetkiniz yok.'], 403);
        }

        $request->validate([
            'content' => 'required|string|max:2000',
        ]);

        $post->update(['content' => $request->content]);

        return response()->json([
            'message' => 'Paylaşım güncellendi.',
            'post' => $post,
        ]);
    }

    public function destroy(Post $post, Request $request): JsonResponse
    {
        if ($post->user_id !== $request->user()->id) {
            return response()->json(['message' => 'Bu paylaşımı silme yetkiniz yok.'], 403);
        }

        $post->update(['status' => 'deleted']);

        return response()->json(['message' => 'Paylaşım silindi.']);
    }

    public function like(Post $post, Request $request): JsonResponse
    {
        if (!Schema::hasTable('post_likes')) {
            return response()->json(['message' => 'Bu özellik henüz aktif değil.', 'is_liked' => false, 'likes_count' => 0], 200);
        }

        $user = $request->user();
        $existing = PostLike::where('post_id', $post->id)->where('user_id', $user->id)->first();

        if ($existing) {
            $existing->delete();
            $isLiked = false;
        } else {
            PostLike::create(['post_id' => $post->id, 'user_id' => $user->id]);
            $isLiked = true;

            if ($post->user_id !== $user->id) {
                try {
                    app(OneSignalService::class)->sendToUser(
                        $post->user_id,
                        'Beğeni',
                        "{$user->name} paylaşımınızı beğendi.",
                        ['type' => 'post_like', 'post_id' => $post->id],
                    );
                } catch (\Exception $e) {
                    \Log::warning('Like bildirim hatası: ' . $e->getMessage());
                }
            }
        }

        return response()->json([
            'is_liked' => $isLiked,
            'likes_count' => $post->likes()->count(),
        ]);
    }

    public function comments(Post $post, Request $request): JsonResponse
    {
        if (!Schema::hasTable('post_comments')) {
            return response()->json(['data' => [], 'total' => 0]);
        }

        $comments = $post->comments()
            ->with('user:id,name,username,avatar,role')
            ->latest()
            ->paginate($request->get('per_page', 20));

        return response()->json($comments);
    }

    public function storeComment(Post $post, Request $request): JsonResponse
    {
        if (!Schema::hasTable('post_comments')) {
            return response()->json(['message' => 'Bu özellik henüz aktif değil.'], 200);
        }

        $request->validate([
            'content' => 'required|string|max:1000',
        ]);

        $comment = PostComment::create([
            'post_id' => $post->id,
            'user_id' => $request->user()->id,
            'content' => $request->content,
        ]);

        $comment->load('user:id,name,username,avatar,role');

        if ($post->user_id !== $request->user()->id) {
            try {
                app(OneSignalService::class)->sendToUser(
                    $post->user_id,
                    'Yeni Yorum',
                    "{$request->user()->name} paylaşımınıza yorum yaptı.",
                    ['type' => 'post_comment', 'post_id' => $post->id],
                );
            } catch (\Exception $e) {
                \Log::warning('Yorum bildirim hatası: ' . $e->getMessage());
            }
        }

        return response()->json([
            'message' => 'Yorum eklendi.',
            'comment' => $comment,
            'comments_count' => $post->comments()->count(),
        ], 201);
    }

    public function destroyComment(PostComment $comment, Request $request): JsonResponse
    {
        if (!Schema::hasTable('post_comments')) {
            return response()->json(['message' => 'Bu özellik henüz aktif değil.'], 200);
        }

        $user = $request->user();
        if ($comment->user_id !== $user->id && $comment->post->user_id !== $user->id) {
            return response()->json(['message' => 'Bu yorumu silme yetkiniz yok.'], 403);
        }

        $postId = $comment->post_id;
        $comment->delete();

        return response()->json([
            'message' => 'Yorum silindi.',
            'comments_count' => PostComment::where('post_id', $postId)->count(),
        ]);
    }

    public function report(Post $post, Request $request): JsonResponse
    {
        if (!Schema::hasTable('post_reports')) {
            return response()->json(['message' => 'Bu özellik henüz aktif değil.'], 200);
        }

        $request->validate([
            'reason' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
        ]);

        $exists = PostReport::where('post_id', $post->id)
            ->where('user_id', $request->user()->id)
            ->exists();

        if ($exists) {
            return response()->json(['message' => 'Bu paylaşımı zaten bildirdiniz.'], 422);
        }

        PostReport::create([
            'post_id' => $post->id,
            'user_id' => $request->user()->id,
            'reason' => $request->reason,
            'description' => $request->description,
        ]);

        return response()->json(['message' => 'Bildiriminiz alındı. Teşekkürler.']);
    }

    public function userPosts(User $user, Request $request): JsonResponse
    {
        $hasLikesTable = Schema::hasTable('post_likes');
        $hasCommentsTable = Schema::hasTable('post_comments');

        $query = Post::active()
            ->where('user_id', $user->id)
            ->with([
                'user:id,name,username,avatar,role',
                'images',
                'tags:id,name,username,avatar',
                'listing:id,title,price,pricing_type',
                'listing.images',
            ]);

        if ($hasCommentsTable) {
            $query->with(['comments' => fn($q) => $q->with('user:id,name,username,avatar')->latest()->limit(2)]);
        }

        $withCounts = [];
        if ($hasLikesTable) $withCounts[] = 'likes';
        if ($hasCommentsTable) $withCounts[] = 'comments';
        if (!empty($withCounts)) {
            $query->withCount($withCounts);
        }

        $posts = $query->latest()->paginate($request->get('per_page', 15));

        $likedPostIds = [];
        if ($request->user() && $hasLikesTable) {
            $likedPostIds = PostLike::where('user_id', $request->user()->id)
                ->whereIn('post_id', $posts->pluck('id'))
                ->pluck('post_id')
                ->toArray();
        }

        $hasSavesTable = Schema::hasTable('post_saves');
        $savedPostIds = [];
        if ($request->user() && $hasSavesTable) {
            $savedPostIds = PostSave::where('user_id', $request->user()->id)
                ->whereIn('post_id', $posts->pluck('id'))
                ->pluck('post_id')
                ->toArray();
        }

        $posts->getCollection()->transform(function ($post) use ($likedPostIds, $savedPostIds, $hasLikesTable, $hasCommentsTable) {
            if (!$hasLikesTable) $post->likes_count = 0;
            if (!$hasCommentsTable) $post->comments_count = 0;
            $post->is_liked = in_array($post->id, $likedPostIds);
            $post->is_saved = in_array($post->id, $savedPostIds);
            return $post;
        });

        return response()->json($posts);
    }

    public function save(Request $request, Post $post): JsonResponse
    {
        $user = $request->user();

        if (!Schema::hasTable('post_saves')) {
            return response()->json(['message' => 'Kaydetme özelliği henüz aktif değil.'], 503);
        }

        $existing = PostSave::where('post_id', $post->id)
            ->where('user_id', $user->id)
            ->first();

        if ($existing) {
            $existing->delete();
            return response()->json(['saved' => false, 'message' => 'Kayıt kaldırıldı.']);
        }

        PostSave::create([
            'post_id' => $post->id,
            'user_id' => $user->id,
        ]);

        return response()->json(['saved' => true, 'message' => 'Gönderi kaydedildi.']);
    }

    public function savedPosts(Request $request): JsonResponse
    {
        $user = $request->user();

        if (!Schema::hasTable('post_saves')) {
            return response()->json(['data' => []]);
        }

        $savedPostIds = PostSave::where('user_id', $user->id)
            ->latest('created_at')
            ->pluck('post_id');

        $hasLikesTable = Schema::hasTable('post_likes');
        $hasCommentsTable = Schema::hasTable('post_comments');

        $query = Post::with(['user:id,name,username,avatar,role', 'images', 'tags:id,name,username,avatar', 'listing.images'])
            ->whereIn('id', $savedPostIds)
            ->active();

        $withCounts = [];
        if ($hasLikesTable) $withCounts[] = 'likes';
        if ($hasCommentsTable) $withCounts[] = 'comments';
        if (!empty($withCounts)) {
            $query->withCount($withCounts);
        }

        $posts = $query->latest()->paginate($request->get('per_page', 15));

        $likedPostIds = [];
        if ($hasLikesTable) {
            $likedPostIds = PostLike::where('user_id', $user->id)
                ->whereIn('post_id', $posts->pluck('id'))
                ->pluck('post_id')
                ->toArray();
        }

        $allSavedIds = $savedPostIds->toArray();

        $posts->getCollection()->transform(function ($post) use ($likedPostIds, $allSavedIds, $hasLikesTable, $hasCommentsTable) {
            if (!$hasLikesTable) $post->likes_count = 0;
            if (!$hasCommentsTable) $post->comments_count = 0;
            $post->is_liked = in_array($post->id, $likedPostIds);
            $post->is_saved = in_array($post->id, $allSavedIds);
            return $post;
        });

        return response()->json($posts);
    }
}
