<?php

namespace App\Http\Controllers\Admin;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Models\ContentRevision;
use App\Models\Page;
use App\Services\ActivityLogger;

class PageController extends Controller
{
    public function index(Request $request, array $params = []): void
    {
        $pages = Page::all('sort_order', 'ASC');
        $view = $this->app->service('view');
        $html = $view->renderAdmin('pages/index', [
            'pageTitle' => __('admin.pages.title'),
            'pages'     => $pages,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
        Response::html($html);
    }

    public function create(Request $request, array $params = []): void
    {
        $view = $this->app->service('view');
        $html = $view->renderAdmin('pages/form', [
            'pageTitle' => __('admin.pages.create'),
            'page'      => null,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
        Response::html($html);
    }

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

        $slug = trim($request->input('slug', ''));
        if (empty($slug)) {
            $slug = slugify($request->input('title', ''));
        }

        $status = $request->input('status', 'draft');

        // Content scheduling fields
        $publishAt   = self::sanitizeDatetime($request->input('publish_at', ''));
        $unpublishAt = self::sanitizeDatetime($request->input('unpublish_at', ''));

        // Auto-correct status based on scheduling
        if ($status === 'scheduled' && $publishAt && strtotime($publishAt) <= time()) {
            $status = 'published';
        }
        if ($status === 'published' && $publishAt && strtotime($publishAt) > time()) {
            $status = 'scheduled';
        }
        // Clear scheduling fields when not relevant
        if ($status === 'draft') {
            $publishAt = null;
        }

        $data = [
            'title'           => trim($request->input('title', '')),
            'slug'            => $slug,
            'content'         => $request->input('content', ''),
            'template'        => $request->input('template', 'page'),
            'status'          => $status,
            'publish_at'      => $publishAt,
            'unpublish_at'    => $unpublishAt ?: null,
            'sort_order'      => (int) $request->input('sort_order', 0),
            'is_homepage'     => (int) $request->input('is_homepage', 0),
            'show_title'      => (int) $request->input('show_title', 1),
            'pagebuilder_enabled' => (int) $request->input('pagebuilder_enabled', 0),
            'seo_title'       => trim($request->input('seo_title', '')),
            'seo_description' => trim($request->input('seo_description', '')),
            'og_image'        => trim($request->input('og_image', '')),
            'robots_meta'     => trim($request->input('robots_meta', '')),
            'canonical_url'   => trim($request->input('canonical_url', '')),
            'custom_css'      => $request->input('custom_css', ''),
            'custom_js'       => $request->input('custom_js', ''),
            'created_by'      => $this->auth()->userId(),
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ];

        // Include page_type only if the column exists (migration 021)
        if (self::hasPageTypeColumn()) {
            $data['page_type'] = 'page';
        }

        Page::create($data);

        $this->clearPageCache();
        ActivityLogger::log('create', 'page', null, $data['title']);
        set_flash('success', __('messages.page_created', ['title' => $slug]));
        Response::redirect(admin_url('pages'));
    }

    public function edit(Request $request, array $params = []): void
    {
        $page = Page::find((int) $params['id']);
        if (!$page) {
            Response::redirect(admin_url('pages'));
            return;
        }

        $view = $this->app->service('view');
        $html = $view->renderAdmin('pages/form', [
            'pageTitle' => __('admin.pages.edit'),
            'page'      => $page,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
        Response::html($html);
    }

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

        $existing = Page::find($id);
        if (!$existing) {
            Response::redirect(admin_url('pages'));
            return;
        }

        // Store revision of current state before update
        ContentRevision::store('page', $id, $existing, $this->auth()->userId());

        $isSystem = Page::isSystemPage($existing);

        // For system pages, preserve slug and template
        if ($isSystem) {
            $slug     = $existing['slug'];
            $template = $existing['template'];
        } else {
            $slug = trim($request->input('slug', ''));
            if (empty($slug)) {
                $slug = slugify($request->input('title', ''));
            }
            $template = $request->input('template', 'page');
        }

        $status = $request->input('status', 'draft');

        // Content scheduling fields
        $publishAt   = self::sanitizeDatetime($request->input('publish_at', ''));
        $unpublishAt = self::sanitizeDatetime($request->input('unpublish_at', ''));

        // Auto-correct status based on scheduling
        if ($status === 'scheduled' && $publishAt && strtotime($publishAt) <= time()) {
            $status = 'published';
        }
        if ($status === 'published' && $publishAt && strtotime($publishAt) > time()) {
            $status = 'scheduled';
        }
        if ($status === 'draft') {
            $publishAt = null;
        }

        Page::updateById($id, [
            'title'           => trim($request->input('title', '')),
            'slug'            => $slug,
            'content'         => $request->input('content', ''),
            'template'        => $template,
            'status'          => $status,
            'publish_at'      => $publishAt,
            'unpublish_at'    => $unpublishAt ?: null,
            'sort_order'      => (int) $request->input('sort_order', 0),
            'is_homepage'     => $isSystem ? (int) $existing['is_homepage'] : (int) $request->input('is_homepage', 0),
            'show_title'      => (int) $request->input('show_title', 1),
            'pagebuilder_enabled' => (int) $request->input('pagebuilder_enabled', 0),
            'seo_title'       => trim($request->input('seo_title', '')),
            'seo_description' => trim($request->input('seo_description', '')),
            'og_image'        => trim($request->input('og_image', '')),
            'robots_meta'     => trim($request->input('robots_meta', '')),
            'canonical_url'   => trim($request->input('canonical_url', '')),
            'custom_css'      => $request->input('custom_css', ''),
            'custom_js'       => $request->input('custom_js', ''),
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        $this->clearPageCache();
        ActivityLogger::log('update', 'page', $id, trim($request->input('title', '')));
        set_flash('success', __('messages.page_updated'));
        Response::redirect(admin_url('pages'));
    }

    public function delete(Request $request, array $params = []): void
    {
        $this->validateCsrf();
        $id   = (int) $params['id'];
        $page = Page::find($id);

        // Prevent deletion of system/module pages
        if ($page && Page::isSystemPage($page)) {
            set_flash('error', __('messages.system_page_delete_error'));
            Response::redirect(admin_url('pages'));
            return;
        }

        Page::deleteById($id);
        $this->clearPageCache();
        ActivityLogger::log('delete', 'page', $id, $page['title'] ?? '');
        set_flash('success', __('messages.page_deleted'));
        Response::redirect(admin_url('pages'));
    }

    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_url('pages'));
            return;
        }

        $count = 0;
        foreach ($ids as $id) {
            $page = Page::find($id);
            if (!$page || Page::isSystemPage($page)) continue;

            if ($action === 'delete') {
                Page::deleteById($id);
                $count++;
            } elseif ($action === 'publish') {
                Page::updateById($id, ['status' => 'published']);
                $count++;
            } elseif ($action === 'draft') {
                Page::updateById($id, ['status' => 'draft']);
                $count++;
            }
        }

        if ($count > 0) {
            $this->clearPageCache();
        }
        set_flash('success', __('messages.bulk_action_done', ['count' => $count]));
        Response::redirect(admin_url('pages'));
    }

    // -------------------------------------------------------------------------
    // CLONE / DUPLICATE
    // -------------------------------------------------------------------------

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

        $id       = (int) $params['id'];
        $original = Page::find($id);

        if (!$original) {
            set_flash('error', __('messages.not_found', ['item' => 'Page']));
            Response::redirect(admin_url('pages'));
            return;
        }

        // Generate a unique slug: {slug}-copy, {slug}-copy-2, ...
        $baseSlug = $original['slug'] . '-copy';
        $newSlug  = $baseSlug;
        $counter  = 2;
        while (Page::findBySlug($newSlug)) {
            $newSlug = $baseSlug . '-' . $counter;
            $counter++;
        }

        $cloneData = [
            'title'           => 'Copy of ' . $original['title'],
            'slug'            => $newSlug,
            'content'         => $original['content'],
            'template'        => $original['template'],
            'status'          => 'draft',
            'sort_order'      => (int) $original['sort_order'],
            'is_homepage'     => 0,         // never carry over homepage flag
            'show_title'      => (int) ($original['show_title'] ?? 1),
            'seo_title'       => $original['seo_title'],
            'seo_description' => $original['seo_description'],
            'og_image'        => null,
            'robots_meta'     => null,
            'canonical_url'   => null,
            'custom_css'      => null,
            'custom_js'       => null,
            'created_by'      => $this->auth()->userId(),
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ];

        // Include page_type only if the column exists (migration 021)
        if (self::hasPageTypeColumn()) {
            $cloneData['page_type'] = 'page';  // clones are always normal pages
        }

        Page::create($cloneData);

        set_flash('success', __('messages.page_duplicated'));
        Response::redirect(admin_url('pages'));
    }

    // -------------------------------------------------------------------------
    // HELPERS
    // -------------------------------------------------------------------------

    /**
     * Sanitize a datetime string from input (datetime-local format).
     * Returns null if empty or invalid.
     */
    private static function sanitizeDatetime(string $value): ?string
    {
        $value = trim($value);
        if ($value === '') {
            return null;
        }
        // datetime-local sends "2026-04-11T14:30" — convert to MySQL format
        $value = str_replace('T', ' ', $value);
        $ts = strtotime($value);
        if ($ts === false) {
            return null;
        }
        return date('Y-m-d H:i:s', $ts);
    }

    /**
     * Check whether the page_type column exists in iw_pages (migration 021).
     * Cached per-request to avoid repeated SHOW COLUMNS queries.
     */
    private static function hasPageTypeColumn(): bool
    {
        static $exists = null;
        if ($exists === null) {
            try {
                $cols = \App\Core\App::getInstance()->db()->fetchAll(
                    "SHOW COLUMNS FROM iw_pages LIKE 'page_type'"
                );
                $exists = !empty($cols);
            } catch (\Exception $e) {
                $exists = false;
            }
        }
        return $exists;
    }
}
