<?php

namespace App\Http\Controllers\Api\V1;

use App\Actions\CreatePlatformAccountAction;
use App\Exceptions\PlatformAuthException;
use App\Http\Requests\StorePlatformAccountRequest;
use App\Http\Resources\PlatformAccountResource;
use App\Models\PlatformAccount;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class PlatformAccountsController extends BaseController
{
    /**
     * Display a listing of platform accounts
     */
    public function index(): JsonResponse
    {
        $accounts = PlatformAccount::orderBy('platform')
            ->orderBy('created_at', 'desc')
            ->get();

        return $this->sendResponse(
            PlatformAccountResource::collection($accounts),
            'Platform accounts retrieved successfully.'
        );
    }

    /**
     * Store a newly created platform account
     */
    public function store(StorePlatformAccountRequest $request, CreatePlatformAccountAction $action): JsonResponse
    {
        try {
            $validated = $request->validated();

            $account = $action->execute(
                $validated['instance_domain'],
                $validated['username'],
                $validated['password'],
                $validated['platform'],
            );

            return $this->sendResponse(
                new PlatformAccountResource($account),
                'Platform account created successfully!',
                201
            );
        } catch (PlatformAuthException $e) {
            if (str_contains($e->getMessage(), 'Rate limited by')) {
                return $this->sendError($e->getMessage(), [], 429);
            }

            return $this->sendError('Invalid username or password. Please check your credentials and try again.', [], 422);
        } catch (Exception $e) {
            return $this->sendError('Unable to connect to the Lemmy instance. Please check the URL and try again.', [], 422);
        }
    }

    /**
     * Display the specified platform account
     */
    public function show(PlatformAccount $platformAccount): JsonResponse
    {
        return $this->sendResponse(
            new PlatformAccountResource($platformAccount),
            'Platform account retrieved successfully.'
        );
    }

    /**
     * Update the specified platform account
     */
    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
    {
        try {
            $validated = $request->validate([
                'instance_url' => 'required|url',
                'username' => 'required|string|max:255',
                'password' => 'nullable|string',
                'settings' => 'nullable|array',
            ]);

            // Don't update password if not provided
            if (empty($validated['password'])) {
                unset($validated['password']);
            }

            $platformAccount->update($validated);

            return $this->sendResponse(
                new PlatformAccountResource($platformAccount->fresh()),
                'Platform account updated successfully!'
            );
        } catch (ValidationException $e) {
            return $this->sendValidationError($e->errors());
        } catch (Exception $e) {
            return $this->sendError('Failed to update platform account: '.$e->getMessage(), [], 500);
        }
    }

    /**
     * Remove the specified platform account
     */
    public function destroy(PlatformAccount $platformAccount): JsonResponse
    {
        try {
            $platformAccount->delete();

            return $this->sendResponse(
                null,
                'Platform account deleted successfully!'
            );
        } catch (Exception $e) {
            return $this->sendError('Failed to delete platform account: '.$e->getMessage(), [], 500);
        }
    }

    /**
     * Set platform account as active
     */
    public function setActive(PlatformAccount $platformAccount): JsonResponse
    {
        try {
            $platformAccount->setAsActive();

            return $this->sendResponse(
                new PlatformAccountResource($platformAccount->fresh()),
                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
            );
        } catch (Exception $e) {
            return $this->sendError('Failed to set platform account as active: '.$e->getMessage(), [], 500);
        }
    }
}
