<?php

namespace App\Http\Controllers;

use App\Models\Post;
use App\Models\SocialAccount;
use App\Models\ActivityLog;
use App\Models\PostPlatform;
use App\Jobs\PublishPostJob;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class PostController extends Controller
{
    public function index()
    {
        $posts = auth()->user()->posts()
            ->with('platforms')
            ->orderBy('created_at', 'desc')
            ->paginate(10);

        return view('posts.index', compact('posts'));
    }

    public function create()
    {
        $accounts = auth()->user()->socialAccounts()->active()->get();
        return view('posts.create', compact('accounts'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'content' => ['required', 'string', 'max:5000'],
            'media' => ['nullable', 'file', 'mimes:jpg,jpeg,png,webp,mp4', 'max:51200'],
            'platforms' => ['required', 'array', 'min:1'],
            'platforms.*' => ['exists:social_accounts,id'],
            'publish_type' => ['required', 'in:now,schedule'],
            'scheduled_at' => ['required_if:publish_type,schedule', 'nullable', 'date', 'after:now'],
        ]);

        $mediaPath = null;
        $mediaType = null;

        if ($request->hasFile('media')) {
            $file = $request->file('media');
            $mediaPath = $file->store('posts', 'public');
            $mediaType = str_starts_with($file->getMimeType(), 'video/') ? 'video' : 'image';
        }

        $status = $validated['publish_type'] === 'now' ? 'published' : 'scheduled';
        $publishedAt = $validated['publish_type'] === 'now' ? now() : null;
        $scheduledAt = $validated['publish_type'] === 'schedule' ? $validated['scheduled_at'] : null;

        $post = auth()->user()->posts()->create([
            'content' => $validated['content'],
            'media_path' => $mediaPath,
            'media_type' => $mediaType,
            'status' => $status,
            'scheduled_at' => $scheduledAt,
            'published_at' => $publishedAt,
        ]);

        foreach ($validated['platforms'] as $accountId) {
            PostPlatform::create([
                'post_id' => $post->id,
                'social_account_id' => $accountId,
                'publish_status' => $status === 'published' ? 'published' : 'pending',
                'published_at' => $status === 'published' ? now() : null,
            ]);
        }

        if ($status === 'published') {
            PublishPostJob::dispatch($post);
        }

        ActivityLog::create([
            'user_id' => auth()->id(),
            'action' => 'create_post',
            'model_type' => Post::class,
            'model_id' => $post->id,
            'description' => "Created post with status: {$status}",
            'ip_address' => $request->ip(),
        ]);

        $message = $status === 'published'
            ? 'Post published successfully.'
            : 'Post scheduled successfully.';

        return redirect()->route('posts.index')
            ->with('success', $message);
    }

    public function show(Post $post)
    {
        $this->authorize('view', $post);
        $post->load('platforms', 'postPlatforms.socialAccount');
        return view('posts.show', compact('post'));
    }

    public function edit(Post $post)
    {
        $this->authorize('update', $post);

        if (in_array($post->status, ['published', 'failed'])) {
            return redirect()->route('posts.index')
                ->with('error', 'Published or failed posts cannot be edited.');
        }

        $accounts = auth()->user()->socialAccounts()->active()->get();
        $selectedPlatforms = $post->platforms->pluck('id')->toArray();

        return view('posts.edit', compact('post', 'accounts', 'selectedPlatforms'));
    }

    public function update(Request $request, Post $post)
    {
        $this->authorize('update', $post);

        if (in_array($post->status, ['published', 'failed'])) {
            return redirect()->route('posts.index')
                ->with('error', 'Published or failed posts cannot be edited.');
        }

        $validated = $request->validate([
            'content' => ['required', 'string', 'max:5000'],
            'media' => ['nullable', 'file', 'mimes:jpg,jpeg,png,webp,mp4', 'max:51200'],
            'platforms' => ['required', 'array', 'min:1'],
            'platforms.*' => ['exists:social_accounts,id'],
            'publish_type' => ['required', 'in:now,schedule'],
            'scheduled_at' => ['required_if:publish_type,schedule', 'nullable', 'date', 'after:now'],
        ]);

        $mediaPath = $post->media_path;
        $mediaType = $post->media_type;

        if ($request->hasFile('media')) {
            if ($post->media_path) {
                Storage::disk('public')->delete($post->media_path);
            }
            $file = $request->file('media');
            $mediaPath = $file->store('posts', 'public');
            $mediaType = str_starts_with($file->getMimeType(), 'video/') ? 'video' : 'image';
        } elseif ($request->boolean('remove_media')) {
            if ($post->media_path) {
                Storage::disk('public')->delete($post->media_path);
            }
            $mediaPath = null;
            $mediaType = null;
        }

        $status = $validated['publish_type'] === 'now' ? 'published' : 'scheduled';
        $publishedAt = $validated['publish_type'] === 'now' ? now() : null;
        $scheduledAt = $validated['publish_type'] === 'schedule' ? $validated['scheduled_at'] : null;

        $post->update([
            'content' => $validated['content'],
            'media_path' => $mediaPath,
            'media_type' => $mediaType,
            'status' => $status,
            'scheduled_at' => $scheduledAt,
            'published_at' => $publishedAt,
        ]);

        $post->postPlatforms()->delete();
        foreach ($validated['platforms'] as $accountId) {
            PostPlatform::create([
                'post_id' => $post->id,
                'social_account_id' => $accountId,
                'publish_status' => $status === 'published' ? 'published' : 'pending',
                'published_at' => $status === 'published' ? now() : null,
            ]);
        }

        if ($status === 'published') {
            PublishPostJob::dispatch($post);
        }

        ActivityLog::create([
            'user_id' => auth()->id(),
            'action' => 'update_post',
            'model_type' => Post::class,
            'model_id' => $post->id,
            'description' => "Updated post with status: {$status}",
            'ip_address' => $request->ip(),
        ]);

        return redirect()->route('posts.index')
            ->with('success', 'Post updated successfully.');
    }

    public function destroy(Post $post)
    {
        $this->authorize('delete', $post);

        if ($post->media_path) {
            Storage::disk('public')->delete($post->media_path);
        }

        ActivityLog::create([
            'user_id' => auth()->id(),
            'action' => 'delete_post',
            'model_type' => Post::class,
            'model_id' => $post->id,
            'description' => 'Deleted post',
            'ip_address' => request()->ip(),
        ]);

        $post->delete();

        return redirect()->route('posts.index')
            ->with('success', 'Post deleted successfully.');
    }

    public function publishNow(Post $post)
    {
        $this->authorize('update', $post);

        if ($post->status !== 'scheduled') {
            return redirect()->route('posts.index')
                ->with('error', 'Only scheduled posts can be published manually.');
        }

        $post->update([
            'status' => 'published',
            'published_at' => now(),
            'scheduled_at' => null,
        ]);

        foreach ($post->postPlatforms as $pp) {
            $pp->update([
                'publish_status' => 'published',
                'published_at' => now(),
            ]);
        }

        PublishPostJob::dispatch($post);

        ActivityLog::create([
            'user_id' => auth()->id(),
            'action' => 'force_publish',
            'model_type' => Post::class,
            'model_id' => $post->id,
            'description' => 'Manually published scheduled post',
            'ip_address' => request()->ip(),
        ]);

        return redirect()->route('posts.index')
            ->with('success', 'Post published successfully.');
    }
}
