<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ url_for('static', filename='font-awesome.css') }}">
    <title>URL 解析器</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background: #f5f5f5; color: #333;
            height: 100vh; overflow-y: auto;
        }
        .container { max-width: 900px; margin: 0 auto; padding: 24px 28px 40px; }

        /* 头部 */
        .header { display: flex; align-items: center; margin-bottom: 2px; }
        .header h1 { font-size: 18px; font-weight: 700; color: #1a1a1a; }
        .subtitle { color: #aaa; font-size: 12px; margin-bottom: 16px; }

        /* 卡片 */
        .section-card {
            background: #fafafa; border: 1px solid #f0f0f0;
            border-radius: 10px; padding: 14px 16px; margin-bottom: 12px;
        }
        .section-title {
            font-size: 11px; font-weight: 600; color: #999;
            text-transform: uppercase; letter-spacing: 0.06em;
            margin-bottom: 12px; display: flex; align-items: center; gap: 6px;
        }
        .section-title i { font-size: 11px; }

        /* 输入 */
        .input-wrap { position: relative; }
        .input-wrap i {
            position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
            color: #c0c0c0; font-size: 12px; pointer-events: none;
        }
        .input-wrap input {
            width: 100%; padding: 9px 12px 9px 32px;
            border: 1px solid #e0e0e0; border-radius: 6px;
            font-size: 13px; outline: none; transition: all 0.15s;
        }
        .input-wrap input::placeholder { color: #c0c0c0; }
        .input-wrap input:focus { border-color: #0078d4; box-shadow: 0 0 0 2px rgba(0,120,212,0.06); }
        .input-wrap input.err { border-color: #c62828; }
        .err-msg { font-size: 12px; color: #c62828; margin-top: 4px; min-height: 16px; }

        /* 按钮 */
        .btn {
            padding: 7px 14px; border: none; border-radius: 6px;
            font-size: 12px; font-weight: 600; cursor: pointer;
            transition: all 0.12s ease;
            display: inline-flex; align-items: center; gap: 5px;
        }
        .btn-outline { background: #fff; color: #666; border: 1px solid #e0e0e0; }
        .btn-outline:hover { background: #f5f5f5; color: #333; }
        .run-btn {
            width: 100%; padding: 10px 18px;
            background: linear-gradient(135deg, #0078d4, #005fa3);
            color: #fff; border: none; border-radius: 8px;
            font-size: 14px; font-weight: 600; cursor: pointer;
            display: flex; align-items: center; justify-content: center; gap: 8px;
            margin-top: 12px; transition: all 0.15s;
            box-shadow: 0 2px 8px rgba(0,120,212,0.2);
        }
        .run-btn:hover { background: linear-gradient(135deg, #006cbd, #004e8a); transform: translateY(-1px); }

        /* 示例列表 */
        .example-list { list-style: none; }
        .example-list li {
            padding: 6px 10px; border-radius: 5px; cursor: pointer;
            font-size: 12px; color: #888; font-family: "SFMono-Regular", Consolas, monospace;
            transition: all 0.15s; margin-bottom: 2px;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        .example-list li:hover { background: #f0f7ff; color: #0078d4; }

        /* 结果 */
        .result-section { margin-bottom: 20px; }
        .result-section:last-child { margin-bottom: 0; }
        .result-title {
            font-size: 11px; font-weight: 700; color: #aaa;
            text-transform: uppercase; letter-spacing: 0.06em;
            margin-bottom: 10px; padding-bottom: 6px;
            border-bottom: 1px solid #eee;
            display: flex; align-items: center; gap: 6px;
        }
        .result-title i { font-size: 11px; color: #ccc; }
        .fields { display: flex; flex-direction: column; gap: 4px; }
        .field-row {
            display: flex; align-items: center; gap: 10px;
            background: #fff; border: 1px solid #e8e8e8; border-radius: 6px;
            padding: 8px 12px; transition: border-color 0.15s;
        }
        .field-row:hover { border-color: #c0c0c0; }
        .field-label { width: 64px; font-size: 12px; font-weight: 600; color: #999; flex-shrink: 0; }
        .field-value {
            flex: 1; font-family: "SFMono-Regular", Consolas, monospace;
            font-size: 12px; color: #333; word-break: break-all; min-width: 0;
        }
        .field-value:empty::after { content: '—'; color: #ddd; }
        .btn-cp {
            padding: 3px 8px; border: 1px solid #e0e0e0; border-radius: 4px;
            background: #fff; color: #aaa; font-size: 11px; cursor: pointer;
            flex-shrink: 0; transition: all 0.15s;
        }
        .btn-cp:hover { background: #f5f5f5; color: #666; }
        .btn-cp.copied { background: #e8f5e9; color: #2e7d32; border-color: #a5d6a7; }

        .params { display: flex; flex-direction: column; gap: 4px; }
        .param-row {
            display: flex; align-items: center; gap: 10px;
            background: #fff; border: 1px solid #e8e8e8; border-radius: 6px;
            padding: 6px 12px; transition: border-color 0.15s;
        }
        .param-row:hover { border-color: #c0c0c0; }
        .param-key {
            width: 120px; flex-shrink: 0;
            padding: 3px 8px; background: #f0f7ff; color: #0078d4;
            border-radius: 4px; font-family: "SFMono-Regular", Consolas, monospace;
            font-size: 12px; font-weight: 600; text-align: center;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        .param-val {
            flex: 1; font-family: "SFMono-Regular", Consolas, monospace;
            font-size: 12px; color: #555; word-break: break-all; min-width: 0;
        }
        .no-params { font-size: 13px; color: #ccc; padding: 8px 0; }

        .empty-state {
            text-align: center; padding: 40px 0; color: #ccc;
        }
        .empty-state i { font-size: 40px; margin-bottom: 12px; display: block; }
        .empty-state p { font-size: 13px; }

        @media (max-width: 768px) {
            .container { padding: 14px 16px 28px; }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1><i class="fas fa-link" style="color:#0078d4;font-size:16px;margin-right:6px;"></i>URL 解析器</h1>
    </div>
    <p class="subtitle">拆解 URL 各组成部分</p>

    <!-- 输入 -->
    <div class="section-card">
        <div class="section-title"><i class="fas fa-pen"></i> 输入 URL</div>
        <div class="input-wrap">
            <i class="fas fa-link"></i>
            <input type="text" id="urlInput" placeholder="粘贴 URL..."
                   value="https://user:pass@example.com:8080/path/to/page?key1=value1&key2=value2#section"
                   onkeydown="if(event.key==='Enter')parse()">
        </div>
        <div class="err-msg" id="errMsg"></div>
        <button class="run-btn" onclick="parse()"><i class="fas fa-search"></i> 解析</button>
    </div>

    <!-- 示例 -->
    <div class="section-card">
        <div class="section-title"><i class="fas fa-lightbulb"></i> 示例</div>
        <ul class="example-list">
            <li onclick="fillUrl(this)">https://user:pass@example.com:8080/path?key=value#hash</li>
            <li onclick="fillUrl(this)">http://localhost:3000/api/v1/users?page=1&limit=20</li>
            <li onclick="fillUrl(this)">https://www.google.com/search?q=hello+world&lang=zh-CN</li>
            <li onclick="fillUrl(this)">ftp://files.example.com:21/pub/doc.pdf</li>
        </ul>
    </div>

    <!-- 结果 -->
    <div class="section-card" id="resultCard" style="display:none;">
        <div class="result-section">
            <div class="result-title"><i class="fas fa-file"></i> URL 组成</div>
            <div class="fields" id="fields"></div>
        </div>
        <div class="result-section" style="margin-top:16px;">
            <div class="result-title"><i class="fas fa-list"></i> Query 参数</div>
            <div id="params"></div>
        </div>
    </div>

    <div class="empty-state" id="emptyState">
        <i class="fas fa-link"></i>
        <p>输入 URL 并点击解析</p>
    </div>
</div>

<script>
var defs = [
    {label:'协议',key:'protocol'},{label:'用户名',key:'username'},{label:'密码',key:'password'},
    {label:'主机名',key:'hostname'},{label:'端口',key:'port'},{label:'路径',key:'pathname'},
    {label:'查询',key:'search'},{label:'哈希',key:'hash'}
];

function esc(s){return(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}

function copyText(text,btn){
    var el=document.createElement('textarea');
    el.value=text;el.style.cssText='position:fixed;left:-9999px';
    document.body.appendChild(el);el.select();document.execCommand('copy');document.body.removeChild(el);
    btn.classList.add('copied');
    setTimeout(function(){btn.classList.remove('copied');},1500);
}

function fillUrl(el){document.getElementById('urlInput').value=el.textContent;parse();}

function parse(){
    var raw=document.getElementById('urlInput').value.trim();
    var errMsg=document.getElementById('errMsg');
    var card=document.getElementById('resultCard');
    var empty=document.getElementById('emptyState');
    var inp=document.getElementById('urlInput');
    if(!raw){errMsg.textContent='';card.style.display='none';empty.style.display='';inp.classList.remove('err');return;}
    try{
        var u=new URL(raw);
        errMsg.textContent='';inp.classList.remove('err');
        card.style.display='';empty.style.display='none';
        var fh='';
        defs.forEach(function(f){
            var v=u[f.key]||'';
            fh+='<div class="field-row"><span class="field-label">'+f.label+'</span>'
                +'<span class="field-value" id="fv-'+f.key+'">'+esc(v)+'</span>'
                +'<button class="btn-cp" onclick="copyText(document.getElementById(\'fv-'+f.key+'\').textContent,this)">复制</button></div>';
        });
        document.getElementById('fields').innerHTML=fh;
        var params=[];
        u.searchParams.forEach(function(v,k){params.push({k:k,v:v});});
        if(params.length){
            var ph='<div class="params">';
            params.forEach(function(p){
                ph+='<div class="param-row"><span class="param-key" title="'+esc(p.k)+'">'+esc(p.k)+'</span>'
                    +'<span class="param-val">'+esc(p.v)+'</span>'
                    +'<button class="btn-cp" onclick="copyText(this.previousElementSibling.textContent,this)">复制</button></div>';
            });
            ph+='</div>';
            document.getElementById('params').innerHTML=ph;
        }else{
            document.getElementById('params').innerHTML='<div class="no-params">无查询参数</div>';
        }
    }catch(e){
        errMsg.textContent='无效的 URL: '+e.message;
        inp.classList.add('err');
        card.style.display='none';empty.style.display='';
    }
}
parse();
</script>
</body>
</html>
