<?php

namespace Botble\Sitemap\Http\Controllers;

use Botble\Base\Services\ClearCacheService;
use Botble\Setting\Http\Controllers\SettingController;
use Botble\Sitemap\Events\SitemapUpdatedEvent;
use Botble\Sitemap\Forms\Settings\SitemapSettingForm;
use Botble\Sitemap\Http\Requests\SitemapSettingRequest;
use Botble\Sitemap\Services\IndexNowService;
use Exception;
use Illuminate\Http\JsonResponse;

class SitemapSettingController extends SettingController
{
    public function edit()
    {
        $this->pageTitle(trans('packages/sitemap::sitemap.settings.title'));

        return SitemapSettingForm::create()->renderForm();
    }

    public function update(SitemapSettingRequest $request)
    {
        $oldItemsPerPage = setting('sitemap_items_per_page');
        $newItemsPerPage = $request->input('sitemap_items_per_page');

        $response = $this->performUpdate($request->validated());

        if ($request->has('indexnow_api_key') && $request->input('indexnow_api_key')) {
            $indexNowService = app(IndexNowService::class);
            $apiKey = $request->input('indexnow_api_key');

            if (! $indexNowService->keyFileExists() || ! $indexNowService->validateKeyFile()) {
                $indexNowService->createKeyFile($apiKey);
            }
        }

        if ($request->has('sitemap_enabled') || ($oldItemsPerPage != $newItemsPerPage && $newItemsPerPage)) {
            ClearCacheService::make()->clearFrameworkCache();

            event(new SitemapUpdatedEvent());
        }

        return $response->withUpdatedSuccessMessage();
    }

    public function generateKey(IndexNowService $indexNowService): JsonResponse
    {
        try {
            $apiKey = $indexNowService->generateApiKey();
            $keyFileExists = $indexNowService->keyFileExists();
            $keyFileValid = $keyFileExists && $indexNowService->validateKeyFile();

            $message = trans('packages/sitemap::sitemap.settings.api_key_generated');

            if ($keyFileExists && $keyFileValid) {
                $message .= ' ' . trans('packages/sitemap::sitemap.settings.key_file_created');
            } elseif ($keyFileExists && ! $keyFileValid) {
                $message .= ' ' . trans('packages/sitemap::sitemap.settings.key_file_created_invalid');
            } else {
                $message .= ' ' . trans('packages/sitemap::sitemap.settings.key_file_creation_failed');
            }

            return response()->json([
                'success' => true,
                'message' => $message,
                'api_key' => $apiKey,
                'key_file_name' => $indexNowService->getApiKeyFileName(),
                'key_file_url' => url($indexNowService->getApiKeyFileName()),
                'key_file_exists' => $keyFileExists,
                'key_file_valid' => $keyFileValid,
                'key_file_path' => $indexNowService->getKeyFilePath(),
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => trans('packages/sitemap::sitemap.settings.generate_key_error'),
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    public function createKeyFile(IndexNowService $indexNowService): JsonResponse
    {
        try {
            $apiKey = $indexNowService->getApiKey();

            if (! $apiKey) {
                return response()->json([
                    'success' => false,
                    'message' => trans('packages/sitemap::sitemap.settings.no_api_key_to_create_file'),
                ], 400);
            }

            $success = $indexNowService->createKeyFile($apiKey);
            $keyFileExists = $indexNowService->keyFileExists();
            $keyFileValid = $keyFileExists && $indexNowService->validateKeyFile();

            if ($success && $keyFileValid) {
                $message = trans('packages/sitemap::sitemap.settings.key_file_created_successfully');
            } elseif ($keyFileExists && ! $keyFileValid) {
                $message = trans('packages/sitemap::sitemap.settings.key_file_created_but_invalid');
            } else {
                $message = trans('packages/sitemap::sitemap.settings.key_file_creation_failed_detailed');
            }

            return response()->json([
                'success' => $success && $keyFileValid,
                'message' => $message,
                'api_key' => $apiKey,
                'key_file_name' => $indexNowService->getApiKeyFileName(),
                'key_file_url' => url($indexNowService->getApiKeyFileName()),
                'key_file_exists' => $keyFileExists,
                'key_file_valid' => $keyFileValid,
                'key_file_path' => $indexNowService->getKeyFilePath(),
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => trans('packages/sitemap::sitemap.settings.key_file_creation_error'),
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    public function submitSitemap(IndexNowService $indexNowService): JsonResponse
    {
        try {
            if (! $indexNowService->isEnabled()) {
                return response()->json([
                    'success' => false,
                    'message' => trans('packages/sitemap::sitemap.settings.indexnow_disabled'),
                ], 400);
            }

            if (! $indexNowService->getApiKey()) {
                return response()->json([
                    'success' => false,
                    'message' => trans('packages/sitemap::sitemap.settings.indexnow_no_api_key'),
                ], 400);
            }

            $results = $indexNowService->submitSitemap();

            $hasSuccess = false;
            $hasError = false;

            foreach ($results as $result) {
                if ($result['status'] === 'success') {
                    $hasSuccess = true;
                } else {
                    $hasError = true;
                }
            }

            $message = trans('packages/sitemap::sitemap.settings.sitemap_submitted_successfully');

            if ($hasError && ! $hasSuccess) {
                $message = trans('packages/sitemap::sitemap.settings.sitemap_submission_failed');
            } elseif ($hasError && $hasSuccess) {
                $message = trans('packages/sitemap::sitemap.settings.sitemap_submission_partial');
            }

            return response()->json([
                'success' => $hasSuccess,
                'message' => $message,
                'results' => $results,
            ]);
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => trans('packages/sitemap::sitemap.settings.submit_sitemap_error'),
                'error' => $e->getMessage(),
            ], 500);
        }
    }
}
