<?php

declare(strict_types=1);

namespace PpPhp\Core\Build;

/**
 * Compiles a Designer common Profile page (an `account_profile` component)
 * into the generated profile.php. Unlike login/register the profile renders
 * INSIDE the application shell, with the signed-in user's real data and the
 * existing full-name update POST handling.
 */
final class ProfilePageCompiler
{
    public static function supports(array $page): bool
    {
        return self::profileProps($page) !== [];
    }

    public static function compile(array $page): string
    {
        $props = self::profileProps($page);
        if ($props === []) {
            throw new \InvalidArgumentException('The Profile page does not contain an account_profile component.');
        }

        $tpl = in_array($props['template'] ?? '', ['cover', 'split', 'verdant'], true) ? $props['template'] : 'card';
        $accent = self::color((string) ($props['accentColor'] ?? '#2563eb'), '#2563eb');
        $cover = self::color((string) ($props['coverColor'] ?? '#0f172a'), '#0f172a');

        $avatar = !empty($props['showAvatar'])
            ? '<span class="pp-prof-avatar is-' . self::e((string) ($props['avatarShape'] ?? 'circle')) . '"><?= $ppProfInitials ?></span>'
            : '';
        $role = !empty($props['showRole']) ? '<span class="pp-prof-role"><?= htmlspecialchars(ucfirst((string) ($user[\'role\'] ?? \'user\'))) ?></span>' : '';

        $rows = '';
        if (!empty($props['showUsername'])) {
            $rows .= '<div class="pp-prof-row"><span>Username</span><strong><?= htmlspecialchars((string) ($user[\'username\'] ?? \'\')) ?></strong></div>';
        }
        // Email is editable in the form below (see $form), so it is no longer a
        // read-only info row when the user is allowed to see/change it.
        if (!empty($props['showRole'])) {
            $rows .= '<div class="pp-prof-row"><span>Role</span><strong><?= htmlspecialchars(ucfirst((string) ($user[\'role\'] ?? \'user\'))) ?></strong></div>';
        }
        if (!empty($props['showJoined'])) {
            $rows .= '<div class="pp-prof-row"><span>Member since</span><strong><?= $ppProfJoined ?></strong></div>';
        }

        $links = '';
        if (!empty($props['showPasswordLink'])) {
            $links .= '<a href="<?= APP_BASE ?>/generated/auth/change-password.php" class="pp-prof-link"><i class="bi bi-key"></i>' .
                self::e((string) ($props['passwordLinkLabel'] ?? 'Change password')) . '</a>';
        }
        if (!empty($props['showLogoutLink'])) {
            $links .= '<a href="<?= APP_BASE ?>/generated/auth/logout.php" class="pp-prof-link is-muted"><i class="bi bi-box-arrow-right"></i>' .
                self::e((string) ($props['logoutLinkLabel'] ?? 'Sign out')) . '</a>';
        }

        $emailField = !empty($props['showEmail'])
            ? '<label class="pp-prof-field"><span>' . self::e((string) ($props['emailLabel'] ?? 'Email address'))
                . '</span><input name="email" type="email" autocomplete="email" placeholder="'
                . self::e((string) ($props['emailPlaceholder'] ?? 'you@example.com'))
                . '" value="<?= htmlspecialchars((string) ($user[\'email\'] ?? \'\')) ?>" required></label>'
            : '';

        $form = '<form method="post" class="pp-prof-form">'
            . '<?= csrfField() ?>'
            . '<label class="pp-prof-field"><span>' . self::e((string) ($props['nameLabel'] ?? 'Full name'))
            . '</span><input name="fullname" placeholder="' . self::e((string) ($props['namePlaceholder'] ?? ''))
            . '" value="<?= htmlspecialchars((string) ($user[\'fullname\'] ?? \'\')) ?>"></label>'
            . $emailField
            . '<button class="pp-prof-save" type="submit">' . self::e((string) ($props['saveLabel'] ?? 'Save changes')) . '</button></form>';

        $head = '<div class="pp-prof-headline"><h2>' . self::e((string) ($props['title'] ?? 'My profile')) . '</h2><p>' .
            self::e((string) ($props['subtitle'] ?? '')) . '</p></div>';
        $name = '<div class="pp-prof-id"><strong><?= htmlspecialchars((string) ($user[\'fullname\'] ?: ($user[\'username\'] ?? \'\'))) ?></strong>' . $role . '</div>';
        $savedFlash = '<?php if ($saved): ?><div class="pp-prof-saved"><i class="bi bi-check-circle"></i> Profile updated.</div><?php endif; ?>'
            . '<?php if ($profErr !== \'\'): ?><div class="pp-prof-error"><i class="bi bi-exclamation-circle"></i> <?= htmlspecialchars($profErr) ?></div><?php endif; ?>';

        $body = match ($tpl) {
            'cover' => '<section class="pp-profile is-cover" style="--prof-accent:var(--pp-primary,' . $accent . ')">'
                . '<div class="pp-prof-cover" style="background:linear-gradient(120deg,' . $cover . ',' . $accent . ')"></div>'
                . '<div class="pp-prof-cover-body">' . $avatar . $name . $head . $savedFlash
                . '<div class="pp-prof-grid">' . $rows . '</div>' . $form . '<div class="pp-prof-links">' . $links . '</div></div></section>',
            'split' => '<section class="pp-profile is-split" style="--prof-accent:var(--pp-primary,' . $accent . ')">'
                . '<aside class="pp-prof-side">' . $avatar . $name . '<div class="pp-prof-links">' . $links . '</div></aside>'
                . '<div class="pp-prof-main">' . $head . $savedFlash . '<div class="pp-prof-grid">' . $rows . '</div>' . $form . '</div></section>',
            'verdant' => '<section class="pp-profile is-verdant" style="--prof-accent:var(--pp-primary,' . $accent . ')">'
                . '<div class="pp-prof-card">' . $avatar . $name . $head . $savedFlash
                . '<div class="pp-prof-grid">' . $rows . '</div>' . $form . '<div class="pp-prof-links">' . $links . '</div></div></section>',
            default => '<section class="pp-profile is-card" style="--prof-accent:var(--pp-primary,' . $accent . ')">'
                . '<div class="pp-prof-card">' . $avatar . $name . $head . $savedFlash
                . '<div class="pp-prof-grid">' . $rows . '</div>' . $form . '<div class="pp-prof-links">' . $links . '</div></div></section>',
        };

        $title = self::e((string) ($props['title'] ?? 'My profile'));

        return strtr(self::documentShell(), [
            '__TITLE__' => $title,
            '__STYLES__' => self::styles(),
            '__BODY__' => $body,
        ]);
    }

    private static function documentShell(): string
    {
        return <<<'PHP'
<?php
require_once __DIR__ . '/../../_runtime.php';
require_once __DIR__ . '/../../app/shell.php';
require_once __DIR__ . '/../../app/lang.php';
\PpPhp\Core\Security::RequireAuth();
$user = \PpPhp\Core\Security::CurrentUserData();
$saved = false;
$profErr = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !\PpPhp\Core\Security::CSRF()->Check((string) ($_POST['_token'] ?? ''))) {
    $profErr = 'Your session has expired. Please refresh the page and try again.';
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $updates = [];
    if (array_key_exists('fullname', $_POST)) {
        $fullname = trim((string) $_POST['fullname']);
        if ($fullname !== '') {
            $updates['fullname'] = $fullname;
        }
    }
    if (array_key_exists('email', $_POST)) {
        $email = trim((string) $_POST['email']);
        if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $profErr = 'Please enter a valid email address.';
        } else {
            try {
                $taken = \PpPhp\Core\DB::FetchAll('SELECT id FROM users WHERE email = ? AND id <> ? LIMIT 1', [$email, $user['id']]);
                if (!empty($taken)) {
                    $profErr = 'That email address is already in use.';
                } else {
                    $updates['email'] = $email;
                }
            } catch (\Throwable $e) {
                $updates['email'] = $email; // no unique index / query failed — still allow the change
            }
        }
    }
    if ($profErr === '' && $updates !== []) {
        \PpPhp\Core\DB::Update('users', $updates, ['id' => $user['id']]);
        if (isset($updates['fullname'])) {
            \PpPhp\Core\Security::SetDisplayName($updates['fullname']);
            $user['fullname'] = $updates['fullname'];
        }
        if (isset($updates['email'])) {
            $user['email'] = $updates['email'];
        }
        $saved = true;
    }
}
// Enrich with columns the session copy may not carry (e.g. created_at)
try {
    $__row = \PpPhp\Core\DB::FetchAll('SELECT * FROM users WHERE id = ?', [$user['id']])[0] ?? [];
    $user = array_merge($__row, array_filter($user, static fn($v) => $v !== null && $v !== ''));
} catch (\Throwable $e) { /* keep session data */ }
$ppProfInitials = strtoupper(substr((string) (($user['fullname'] ?? '') !== '' ? $user['fullname'] : ($user['username'] ?? 'U')), 0, 2));
$ppProfJoined = !empty($user['created_at']) ? date('M Y', strtotime((string) $user['created_at'])) : '—';
?><!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>__TITLE__</title>
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/icons/bootstrap-icons.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/css/designer-base.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/inter/inter.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/fonts/fonts.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/fontawesome/7.2/css/fontawesome.min.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/fontawesome/7.2/css/solid.min.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/fontawesome/7.2/css/regular.min.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/vendor/material-symbols/material-symbols.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/css/theme.css">
<link rel="stylesheet" href="<?= APP_BASE ?>/assets/css/shell.css">
<style>__STYLES__</style>
</head>
<body>
<?php pp_shell_start('__TITLE__', ''); ?>
__BODY__
<?php pp_shell_end(); ?>
</body>
</html>
PHP;
    }

    private static function styles(): string
    {
        return <<<'CSS'
.pp-profile{color:var(--pp-text,#0f172a)}
.pp-prof-avatar{width:64px;height:64px;display:grid;place-items:center;background:linear-gradient(140deg,color-mix(in srgb,var(--prof-accent) 82%,#fff),var(--prof-accent));color:#fff;font-weight:800;font-size:20px;flex-shrink:0;box-shadow:0 8px 20px color-mix(in srgb,var(--prof-accent) 32%,transparent)}
.pp-prof-avatar.is-circle{border-radius:50%}.pp-prof-avatar.is-rounded{border-radius:16px}
.pp-prof-role{display:inline-block;background:color-mix(in srgb,var(--prof-accent) 12%,var(--pp-surface,#fff));color:var(--prof-accent);border-radius:999px;padding:2px 10px;font-size:10.5px;font-weight:800}
.pp-prof-id{display:flex;align-items:center;gap:10px;margin-top:10px}.pp-prof-id strong{font-size:16px}
.pp-prof-headline h2{margin:14px 0 2px;font-size:20px;letter-spacing:-.02em}
.pp-prof-headline p{margin:0 0 14px;color:var(--pp-muted,#64748b);font-size:12.5px}
.pp-prof-saved{margin:0 0 12px;padding:9px 12px;border-radius:10px;font-size:12px;border:1px solid color-mix(in srgb,var(--pp-success,#16a34a) 40%,transparent);background:color-mix(in srgb,var(--pp-success,#16a34a) 10%,var(--pp-surface,#fff));color:var(--pp-success,#166534);display:flex;align-items:center;gap:7px}
.pp-prof-error{margin:0 0 12px;padding:9px 12px;border-radius:10px;font-size:12px;border:1px solid color-mix(in srgb,var(--pp-danger,#dc2626) 40%,transparent);background:color-mix(in srgb,var(--pp-danger,#dc2626) 10%,var(--pp-surface,#fff));color:var(--pp-danger,#b91c1c);display:flex;align-items:center;gap:7px}
.pp-prof-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:8px;margin-bottom:14px}
.pp-prof-row{border:1px solid var(--pp-border,#e2e8f0);border-radius:10px;padding:8px 11px;background:var(--pp-surface-soft,#f8fafc)}
.pp-prof-row span{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--pp-muted,#94a3b8);font-weight:700}
.pp-prof-row strong{font-size:13px}
.pp-prof-field{display:grid;gap:5px;font-size:11.5px;font-weight:700;margin-bottom:10px}
.pp-prof-field input{height:38px;border:1px solid var(--pp-border,#dfe3ec);border-radius:9px;padding:0 12px;font:inherit;background:var(--pp-surface,#fff);color:var(--pp-text,#0f172a)}
.pp-prof-save{border:0;border-radius:9px;height:38px;padding:0 18px;background:var(--prof-accent);color:#fff;font-weight:750;cursor:pointer}
.pp-prof-links{display:flex;gap:14px;margin-top:12px}
.pp-prof-link{display:inline-flex;align-items:center;gap:6px;color:var(--prof-accent);font-size:12px;font-weight:700;text-decoration:none}
.pp-prof-link.is-muted{color:var(--pp-muted,#64748b)}
.pp-profile.is-card{display:grid;place-items:start center;padding:8px 0}
.pp-profile.is-card .pp-prof-card{width:min(100%,520px);background:var(--pp-surface,#fff);border:1px solid var(--pp-border,#e2e8f0);border-radius:18px;padding:26px;box-shadow:var(--pp-shadow,0 14px 40px rgba(15,23,42,.07))}
.pp-profile.is-cover .pp-prof-cover{height:120px;border-radius:16px 16px 0 0}
.pp-profile.is-cover .pp-prof-cover-body{background:var(--pp-surface,#fff);border:1px solid var(--pp-border,#e2e8f0);border-top:0;border-radius:0 0 16px 16px;padding:0 26px 24px}
.pp-profile.is-cover .pp-prof-avatar{margin-top:-32px;border:4px solid var(--pp-surface,#fff)}
.pp-profile.is-split{display:grid;grid-template-columns:230px 1fr;gap:16px;align-items:start}
.pp-profile.is-split .pp-prof-side{background:var(--pp-surface,#fff);border:1px solid var(--pp-border,#e2e8f0);border-radius:16px;padding:22px;display:grid;justify-items:center;text-align:center;gap:8px}
.pp-profile.is-split .pp-prof-side .pp-prof-links{flex-direction:column;gap:8px;align-items:center}
.pp-profile.is-split .pp-prof-main{background:var(--pp-surface,#fff);border:1px solid var(--pp-border,#e2e8f0);border-radius:16px;padding:22px 26px}
.pp-profile.is-verdant{position:relative;isolation:isolate;overflow:hidden;display:grid;place-items:center;min-height:clamp(540px,72vh,760px);padding:clamp(22px,5vw,64px);border-radius:22px;color:#fff;background:radial-gradient(ellipse at 72% 103%,#77ad26 0 18%,transparent 18.4%),radial-gradient(ellipse at 25% 110%,#91bf31 0 26%,transparent 26.4%),linear-gradient(160deg,transparent 52%,#3b731f 52.3% 67%,#244c22 67.4% 100%),linear-gradient(180deg,#a9ced2 0%,#eed49f 43%,#79945f 64%,#284c2a 100%)}
.pp-profile.is-verdant:before{content:"";position:absolute;inset:0;z-index:-1;opacity:.55;background:radial-gradient(ellipse at 6% 60%,rgba(22,51,48,.8) 0 10%,transparent 10.5%),linear-gradient(115deg,transparent 0 56%,rgba(255,230,153,.18) 56.2% 57%,transparent 57.2%)}
.pp-profile.is-verdant .pp-prof-card{width:min(100%,580px);padding:clamp(24px,4vw,42px);border:1px solid rgba(255,255,255,.58);border-radius:28px;background:linear-gradient(145deg,rgba(255,255,255,.25),rgba(11,38,28,.34));box-shadow:0 28px 70px rgba(8,25,18,.32),inset 0 1px rgba(255,255,255,.5);-webkit-backdrop-filter:blur(22px) saturate(125%);backdrop-filter:blur(22px) saturate(125%)}
.pp-profile.is-verdant .pp-prof-headline p,.pp-profile.is-verdant .pp-prof-row span{color:rgba(255,255,255,.74)}
.pp-profile.is-verdant .pp-prof-row,.pp-profile.is-verdant .pp-prof-field input{color:#fff;background:rgba(7,31,24,.23);border-color:rgba(255,255,255,.42)}
.pp-profile.is-verdant .pp-prof-field input::placeholder{color:rgba(255,255,255,.62)}
.pp-profile.is-verdant .pp-prof-role{background:rgba(255,255,255,.18);color:#fff}
.pp-profile.is-verdant .pp-prof-save{background:linear-gradient(100deg,#c2d508,#27bf68);box-shadow:0 10px 26px rgba(42,178,82,.28)}
.pp-profile.is-verdant .pp-prof-link{color:#eaffae}.pp-profile.is-verdant .pp-prof-link.is-muted{color:rgba(255,255,255,.75)}
@media(max-width:720px){.pp-profile.is-split{grid-template-columns:1fr}.pp-profile.is-verdant{min-height:560px;padding:18px;border-radius:16px}.pp-profile.is-verdant .pp-prof-card{padding:24px 20px;border-radius:22px}}
CSS;
    }

    private static function profileProps(array $page): array
    {
        $walk = function (array $components) use (&$walk): array {
            foreach ($components as $component) {
                if (!is_array($component)) {
                    continue;
                }
                if (($component['type'] ?? '') === 'account_profile') {
                    return (array) ($component['props'] ?? []);
                }
                $found = $walk((array) ($component['children'] ?? []));
                if ($found !== []) {
                    return $found;
                }
            }
            return [];
        };

        return $walk((array) ($page['components'] ?? []));
    }

    private static function color(string $value, string $fallback): string
    {
        return preg_match('/^#[0-9a-f]{3,8}$/i', $value) ? $value : $fallback;
    }

    private static function e(string $value): string
    {
        return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
    }
}
