<?php
/**
 * Admin login page (also serves client users — type isolation enforced
 * elsewhere). URL: http://localhost/medmecs/login.php
 */
require_once __DIR__ . '/includes/config.php';
start_session();

if (is_logged_in()) {
    redirect('/dashboard.php');
}

$errors = [];
$emailVal = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_check_or_die();

    $emailVal = trim((string) input('email'));
    $password = (string) input('password');
    $emailLc  = strtolower($emailVal);

    // No rate-limiting, no lockout — only active / inactive status matters.
    // Bad-password attempts still recorded to login_attempts log for audit, but
    // never cause the account to be locked, throttled, or barred from retry.
    if ($emailVal === '' || $password === '') {
        $errors[] = 'Both email and password are required.';
    } else {
        $stmt = db()->prepare(
            'SELECT id, name, email, password, user_type, client_id, status,
                    must_change_password
             FROM users WHERE email = ? LIMIT 1'
        );
        $stmt->execute([$emailLc]);
        $user = $stmt->fetch();

        $generic = 'Invalid email or password.';

        if (!$user) {
            login_log_attempt(null, $emailLc, 'failed', 'No such user');
            $errors[] = $generic;
        } elseif ($user['status'] === 'inactive') {
            login_log_attempt((int) $user['id'], $emailLc, 'failed', 'Inactive');
            $errors[] = 'Your account is inactive. Contact your administrator.';
        } elseif (!password_verify($password, $user['password'])) {
            login_log_attempt((int) $user['id'], $emailLc, 'failed', 'Bad password');
            $errors[] = $generic;
        } else {
            // Success.
            db()->prepare(
                'UPDATE users
                 SET last_login_at = NOW(), last_login_ip = ?,
                     login_attempts = 0, locked_until = NULL, status = "active"
                 WHERE id = ?'
            )->execute([client_ip(), $user['id']]);

            login_user($user);
            login_log_attempt((int) $user['id'], $emailLc, 'success');

            if (!empty($user['must_change_password'])) {
                redirect('/change-password.php');
            }
            // Role/type-based routing — ONE login URL for everyone. Client-portal users land on their
            // branded client portal (reports scoped to their client + grants); staff go to the internal
            // dashboard, which itself routes by role (sysadmin / report-viewer / coding / billing / AR).
            if ($user['user_type'] === 'client') {
                $slug = db()->prepare('SELECT login_slug FROM client_branding WHERE client_id=?');
                $slug->execute([(int) $user['client_id']]); $slug = (string) $slug->fetchColumn();
                redirect('/client/overall.php' . ($slug !== '' ? '?slug=' . urlencode($slug) : ''));
            }
            redirect('/dashboard.php');
        }
    }
}
$flashError = flash_take('error');
?><!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
    <meta name="theme-color" content="#0a0f1e"/>
    <title>Sign in &mdash; <?= e(APP_NAME) ?></title>
    <link href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@2.47.0/tabler-icons.min.css" rel="stylesheet"/>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"/>
    <style>
        *{box-sizing:border-box}
        html,body{margin:0;height:100%}
        body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:#1e293b;background:#f8fafc;min-height:100vh;overflow-x:hidden}
        .shell{display:grid;grid-template-columns:1.08fr 1fr;min-height:100vh}

        /* ================= LEFT — INFO / BRAND ================= */
        .brand{position:relative;overflow:hidden;color:#fff;padding:30px 42px;display:flex;flex-direction:column;justify-content:space-between;
            background:
              radial-gradient(1000px 620px at 12% 6%,  rgba(56,189,248,.34), transparent 56%),
              radial-gradient(820px 560px at 92% 96%, rgba(139,92,246,.34), transparent 56%),
              radial-gradient(620px 480px at 88% 4%,  rgba(34,211,238,.18), transparent 56%),
              linear-gradient(155deg,#070b16 0%,#0c1530 48%,#0a1124 100%);}
        .brand::before{content:'';position:absolute;inset:0;
            background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
            background-size:38px 38px;-webkit-mask-image:radial-gradient(ellipse at center,#000 28%,transparent 80%);mask-image:radial-gradient(ellipse at center,#000 28%,transparent 80%);pointer-events:none}
        .orb{position:absolute;border-radius:50%;filter:blur(58px);opacity:.5;pointer-events:none;animation:float 16s ease-in-out infinite}
        .orb-1{width:300px;height:300px;background:#38bdf8;top:-70px;right:8%}
        .orb-2{width:240px;height:240px;background:#a855f7;bottom:16%;left:-50px;animation-delay:-5s}
        .orb-3{width:180px;height:180px;background:#06b6d4;bottom:6%;right:20%;animation-delay:-9s}
        @keyframes float{0%,100%{transform:translate(0,0) scale(1)}33%{transform:translate(22px,-26px) scale(1.07)}66%{transform:translate(-16px,16px) scale(.95)}}
        .brand-in{position:relative;z-index:1}

        .mark{display:inline-flex;align-items:center;gap:11px;font-weight:800;font-size:1.2rem;opacity:0;animation:up .7s .15s forwards}
        .mark .lg{width:40px;height:40px;border-radius:12px;display:grid;place-items:center;background:linear-gradient(135deg,#38bdf8,#a855f7);box-shadow:0 10px 26px rgba(56,189,248,.4);animation:pulse 3.4s ease-in-out infinite}
        .mark .lg i{font-size:1.3rem}
        @keyframes pulse{0%,100%{transform:scale(1);box-shadow:0 10px 26px rgba(56,189,248,.4)}50%{transform:scale(1.06);box-shadow:0 14px 34px rgba(168,85,247,.5)}}

        .headline{font-size:2rem;font-weight:800;line-height:1.08;margin:26px 0 11px;opacity:0;animation:up .8s .35s forwards}
        .headline .ac{background:linear-gradient(90deg,#38bdf8,#a855f7);-webkit-background-clip:text;background-clip:text;color:transparent}
        .lede{font-size:.9rem;color:rgba(255,255,255,.74);max-width:480px;line-height:1.5;opacity:0;animation:up .8s .5s forwards}

        .feats{margin-top:20px;display:grid;grid-template-columns:1fr 1fr;gap:11px 22px}
        .feat{display:flex;gap:10px;align-items:flex-start;opacity:0;animation:up .6s forwards}
        .feat:nth-child(1){animation-delay:.62s}.feat:nth-child(2){animation-delay:.72s}.feat:nth-child(3){animation-delay:.82s}.feat:nth-child(4){animation-delay:.92s}
        .feat .fi{width:28px;height:28px;flex-shrink:0;display:grid;place-items:center;border-radius:8px;background:rgba(56,189,248,.12);border:1px solid rgba(56,189,248,.28)}
        .feat .fi i{font-size:1rem;color:#7dd3fc}
        .feat h4{margin:0 0 1px;font-size:.85rem;font-weight:600}
        .feat p{margin:0;font-size:.75rem;color:rgba(255,255,255,.62);line-height:1.38}

        .stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:20px;padding:13px 0;border-top:1px solid rgba(255,255,255,.13);border-bottom:1px solid rgba(255,255,255,.13)}
        .stat .n{font-size:1.5rem;font-weight:800;line-height:1;display:inline-flex;align-items:baseline;background:linear-gradient(90deg,#fff,#cbd5e1);-webkit-background-clip:text;background-clip:text;color:transparent}
        .stat .sfx{font-size:.95rem;font-weight:700;margin-left:2px;background:linear-gradient(90deg,#38bdf8,#a855f7);-webkit-background-clip:text;background-clip:text;color:transparent}
        .stat .l{font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:rgba(255,255,255,.55);margin-top:5px}
        .brand-foot{position:relative;z-index:1;font-size:.8rem;color:rgba(255,255,255,.45);opacity:0;animation:up .8s 1.05s forwards}

        /* ================= RIGHT — FORM ================= */
        .formp{display:flex;align-items:center;justify-content:center;padding:30px;background:#f8fafc}
        .formc{width:100%;max-width:392px;opacity:0;animation:up .8s .25s forwards}
        .ftitle{font-size:1.4rem;font-weight:700;color:#0f172a;margin:0 0 5px}
        .fsub{color:#64748b;margin:0 0 18px;font-size:.86rem}

        .field{position:relative;margin-bottom:11px}
        .field input{width:100%;height:46px;padding:12px 42px;font-size:.9rem;border:1.5px solid #e2e8f0;border-radius:11px;background:#fff;color:#0f172a;transition:.15s;font-family:inherit;outline:0}
        .field input::placeholder{color:#94a3b8}
        .field input:focus{border-color:#3b82f6;box-shadow:0 0 0 4px rgba(59,130,246,.14)}
        .field .ic{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:#94a3b8;font-size:1.05rem;pointer-events:none;transition:.15s}
        .field input:focus ~ .ic{color:#3b82f6}
        .field .toggle{position:absolute;right:9px;top:50%;transform:translateY(-50%);background:0;border:0;cursor:pointer;color:#94a3b8;padding:7px;border-radius:8px;line-height:0}
        .field .toggle:hover{color:#3b82f6;background:#f1f5f9}

        .btn{width:100%;height:46px;border:0;border-radius:11px;cursor:pointer;margin-top:6px;font-size:.92rem;font-weight:600;color:#fff;font-family:inherit;
            background:linear-gradient(90deg,#2563eb,#6d28d9);display:flex;align-items:center;justify-content:center;gap:9px;
            box-shadow:0 12px 26px rgba(37,99,235,.32);transition:transform .14s,box-shadow .16s;position:relative;overflow:hidden}
        .btn:hover{transform:translateY(-1px);box-shadow:0 16px 34px rgba(109,40,217,.42)}
        .btn:active{transform:translateY(0)}.btn:disabled{opacity:.85;cursor:default}
        .btn::after{content:'';position:absolute;top:0;left:-130%;width:55%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.28),transparent);transform:skewX(-20deg);transition:left .6s}
        .btn:hover::after{left:140%}

        .astack{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
        .al{display:flex;gap:9px;align-items:flex-start;padding:11px 13px;border-radius:10px;font-size:.85rem;line-height:1.35;animation:shake .35s ease-out}
        .al i{font-size:1rem;margin-top:1px;flex-shrink:0}
        .al.err{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}
        .al.ok{background:#f0fdf4;border:1px solid #bbf7d0;color:#14532d}
        @keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}

        .ffoot{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:12px;border-top:1px solid #e2e8f0;font-size:.74rem;color:#94a3b8}
        .dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.18);margin-right:6px;animation:blink 2s ease-in-out infinite;vertical-align:middle}
        @keyframes blink{0%,100%{opacity:1}50%{opacity:.45}}

        @keyframes up{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
        @keyframes spin{to{transform:rotate(360deg)}}

        @media (max-width:992px){
            .shell{grid-template-columns:1fr}
            .brand{padding:32px 28px}
            .headline{font-size:2rem;margin-top:26px}
            .feats{display:none}
            .stats{margin-top:26px}
            .formp{padding:34px 24px}
        }
        @media (max-width:480px){ .stats{grid-template-columns:1fr;gap:10px;text-align:center} .brand-foot{display:none} }
    </style>
</head>
<body>
<div class="shell">

    <!-- ============ LEFT: INFO / BRAND ============ -->
    <aside class="brand">
        <span class="orb orb-1"></span><span class="orb orb-2"></span><span class="orb orb-3"></span>
        <div class="brand-in">
            <div class="mark"><span class="lg"><i class="ti ti-chart-pie-2"></i></span><?= e(APP_NAME) ?></div>

            <h1 class="headline">Replace manual MIS<br>with <span class="ac">automated dashboards</span></h1>
            <p class="lede">Turn raw EHR exports into client-ready Excel, summary, pivot, and detail reports in seconds &mdash; with full audit trail and per-client branded portals.</p>

            <div class="feats">
                <div class="feat"><span class="fi"><i class="ti ti-table-import"></i></span><div><h4>Drop-in ingestion</h4><p>Upload .xlsx, .xls, .csv. Validates, ingests, materializes outputs.</p></div></div>
                <div class="feat"><span class="fi"><i class="ti ti-layout-dashboard"></i></span><div><h4>4 outputs from 1 upload</h4><p>Dashboard, Summary, Pivot drill-down, Raw detail.</p></div></div>
                <div class="feat"><span class="fi"><i class="ti ti-shield-lock"></i></span><div><h4>Audit-grade access</h4><p>Roles, scoped permissions, full login + change history.</p></div></div>
                <div class="feat"><span class="fi"><i class="ti ti-color-swatch"></i></span><div><h4>Branded client portals</h4><p>Client logo, color, custom slug, scoped data isolation.</p></div></div>
            </div>

            <div class="stats">
                <div class="stat"><div class="n"><span data-target="20">0</span><span class="sfx">+</span></div><div class="l">Hours saved every week</div></div>
                <div class="stat"><div class="n"><span data-target="4">0</span><span class="sfx">-in-1</span></div><div class="l">Outputs per upload</div></div>
                <div class="stat"><div class="n"><span data-target="100">0</span><span class="sfx">%</span></div><div class="l">Audit traceable</div></div>
            </div>
        </div>
        <div class="brand-foot">&copy; <?= date('Y') ?> <?= e(APP_NAME) ?> &middot; v1.0 &middot; PHP <?= phpversion() ?></div>
    </aside>

    <!-- ============ RIGHT: SIGN-IN FORM ============ -->
    <main class="formp">
        <div class="formc">
            <h2 class="ftitle">Welcome back</h2>
            <p class="fsub">Sign in to your <?= e(APP_NAME) ?> account.</p>

            <div class="astack">
                <?php foreach (array_merge($errors, $flashError) as $m): ?>
                    <div class="al err"><i class="ti ti-alert-circle"></i><span><?= e($m) ?></span></div>
                <?php endforeach; ?>
                <?php foreach (flash_take('success') as $m): ?>
                    <div class="al ok"><i class="ti ti-circle-check"></i><span><?= e($m) ?></span></div>
                <?php endforeach; ?>
            </div>

            <form method="POST" action="<?= e(url('/login.php')) ?>" autocomplete="off" novalidate id="loginForm">
                <?= csrf_field() ?>
                <div class="field">
                    <input type="email" id="email" name="email" placeholder="Email address" value="<?= e($emailVal) ?>" autofocus required>
                    <i class="ti ti-mail ic"></i>
                </div>
                <div class="field">
                    <input type="password" id="password" name="password" placeholder="Password" required>
                    <i class="ti ti-lock ic"></i>
                    <button type="button" class="toggle" onclick="togglePw()" tabindex="-1" aria-label="Show password"><i class="ti ti-eye" id="pwEye"></i></button>
                </div>
                <button type="submit" class="btn"><i class="ti ti-login-2"></i><span>Sign in</span></button>
            </form>

            <div class="ffoot">
                <span><span class="dot"></span>System operational</span>
                <span><?= e(APP_NAME) ?> &middot; secure portal</span>
            </div>
        </div>
    </main>

</div>

<script>
    function togglePw(){
        var i = document.getElementById('password'), e = document.getElementById('pwEye');
        i.type = i.type === 'password' ? 'text' : 'password';
        e.classList.toggle('ti-eye'); e.classList.toggle('ti-eye-off');
    }
    /* Count-up stat animation */
    document.querySelectorAll('.stat .n [data-target]').forEach(function(el){
        var target = parseInt(el.dataset.target, 10) || 0;
        if (!target) { el.textContent = '0'; return; }
        var dur = 1300, start = performance.now();
        function tick(now){
            var t = Math.min(1, (now - start) / dur), eased = 1 - Math.pow(1 - t, 3);
            el.textContent = Math.floor(eased * target).toLocaleString();
            if (t < 1) requestAnimationFrame(tick); else el.textContent = target.toLocaleString();
        }
        requestAnimationFrame(tick);
    });
    document.getElementById('loginForm').addEventListener('submit', function(){
        var b = this.querySelector('.btn');
        b.innerHTML = '<i class="ti ti-loader-2" style="animation:spin 1s linear infinite"></i><span>Signing in&hellip;</span>';
        b.disabled = true;
    });
</script>
</body>
</html>
