<?php

namespace App\Http\Controllers\Admin;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Models\Redirect;
use App\Services\ActivityLogger;

class RedirectController extends Controller
{
    public function index(Request $request, array $params = []): void
    {
        $page = max(1, (int) $request->query('page', 1));
        $data = Redirect::paginated($page);

        $this->renderAdmin('redirects/index', [
            'pageTitle'  => __('admin.redirects.title'),
            'redirects'  => $data['items'],
            'pagination' => $data,
            'auth'       => $this->auth(),
            'csrf'       => $this->csrf(),
        ]);
    }

    public function create(Request $request, array $params = []): void
    {
        $this->renderAdmin('redirects/form', [
            'pageTitle' => __('admin.redirects.create'),
            'redirect'  => null,
            'old'       => [],
            'errors'    => [],
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
    }

    public function store(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $data   = $this->extractFormData($request);
        $errors = $this->validate($data);

        if (!empty($errors)) {
            $this->renderAdmin('redirects/form', [
                'pageTitle' => __('admin.redirects.create'),
                'redirect'  => null,
                'old'       => $data,
                'errors'    => $errors,
                'auth'      => $this->auth(),
                'csrf'      => $this->csrf(),
            ]);
            return;
        }

        Redirect::create([
            'source_path' => $data['source_path'],
            'target_url'  => $data['target_url'],
            'status_code' => $data['status_code'],
            'is_active'   => $data['is_active'],
            'created_at'  => date('Y-m-d H:i:s'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ]);

        ActivityLogger::log('create', 'redirect', null, $data['source_path'] . ' → ' . $data['target_url']);
        set_flash('success', __('admin.redirects.created'));
        Response::redirect('/admin/redirects');
    }

    public function edit(Request $request, array $params = []): void
    {
        $id       = (int) ($params['id'] ?? 0);
        $redirect = Redirect::find($id);

        if (!$redirect) {
            set_flash('error', __('messages.not_found', ['item' => 'Redirect']));
            Response::redirect('/admin/redirects');
            return;
        }

        $this->renderAdmin('redirects/form', [
            'pageTitle' => __('admin.redirects.edit'),
            'redirect'  => $redirect,
            'old'       => $redirect,
            'errors'    => [],
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
    }

    public function update(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id       = (int) ($params['id'] ?? 0);
        $redirect = Redirect::find($id);

        if (!$redirect) {
            set_flash('error', __('messages.not_found', ['item' => 'Redirect']));
            Response::redirect('/admin/redirects');
            return;
        }

        $data   = $this->extractFormData($request);
        $errors = $this->validate($data, $id);

        if (!empty($errors)) {
            $this->renderAdmin('redirects/form', [
                'pageTitle' => __('admin.redirects.edit'),
                'redirect'  => $redirect,
                'old'       => $data,
                'errors'    => $errors,
                'auth'      => $this->auth(),
                'csrf'      => $this->csrf(),
            ]);
            return;
        }

        Redirect::updateById($id, [
            'source_path' => $data['source_path'],
            'target_url'  => $data['target_url'],
            'status_code' => $data['status_code'],
            'is_active'   => $data['is_active'],
            'updated_at'  => date('Y-m-d H:i:s'),
        ]);

        ActivityLogger::log('update', 'redirect', $id, $data['source_path']);
        set_flash('success', __('admin.redirects.updated'));
        Response::redirect('/admin/redirects');
    }

    public function delete(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id = (int) ($params['id'] ?? 0);
        $redirect = Redirect::find($id);

        if ($redirect) {
            Redirect::deleteById($id);
            ActivityLogger::log('delete', 'redirect', $id, $redirect['source_path'] ?? '');
            set_flash('success', __('admin.redirects.deleted'));
        }

        Response::redirect('/admin/redirects');
    }

    public function bulk(Request $request, array $params = []): void
    {
        $this->validateCsrf();
        $ids    = array_map('intval', $request->input('ids', []));
        $action = $request->input('bulk_action', '');

        if (empty($ids)) {
            Response::redirect('/admin/redirects');
            return;
        }

        $count = 0;
        foreach ($ids as $id) {
            if ($action === 'delete') {
                Redirect::deleteById($id);
                $count++;
            } elseif ($action === 'activate') {
                Redirect::updateById($id, ['is_active' => 1]);
                $count++;
            } elseif ($action === 'deactivate') {
                Redirect::updateById($id, ['is_active' => 0]);
                $count++;
            }
        }

        set_flash('success', __('messages.bulk_action_done', ['count' => $count]));
        Response::redirect('/admin/redirects');
    }

    private function extractFormData(Request $request): array
    {
        $sourcePath = trim($request->input('source_path', ''));
        // Ensure source path starts with /
        if ($sourcePath !== '' && $sourcePath[0] !== '/') {
            $sourcePath = '/' . $sourcePath;
        }

        return [
            'source_path' => $sourcePath,
            'target_url'  => trim($request->input('target_url', '')),
            'status_code' => (int) $request->input('status_code', 301),
            'is_active'   => $request->input('is_active', '0') === '1' ? 1 : 0,
        ];
    }

    private function validate(array $data, ?int $currentId = null): array
    {
        $errors = [];

        if (empty($data['source_path'])) {
            $errors['source_path'] = __('admin.redirects.error_source_required');
        } else {
            // Check for duplicate source path
            $existing = Redirect::findWhere(['source_path' => $data['source_path']]);
            if ($existing && (int) $existing['id'] !== $currentId) {
                $errors['source_path'] = __('admin.redirects.error_source_exists');
            }
        }

        if (empty($data['target_url'])) {
            $errors['target_url'] = __('admin.redirects.error_target_required');
        }

        if (!in_array($data['status_code'], [301, 302], true)) {
            $errors['status_code'] = __('admin.redirects.error_invalid_status');
        }

        // Prevent redirect loops
        if ($data['source_path'] === $data['target_url']) {
            $errors['target_url'] = __('admin.redirects.error_loop');
        }

        return $errors;
    }
}
