"""Install this skill from a local bundle or pinned public files. No Git required."""
import argparse
from concurrent.futures import ThreadPoolExecutor
import hashlib
import json
from pathlib import Path, PurePosixPath
import shutil
import sys
import tempfile
import urllib.request

REPO='SJ3199/video-script-pro'
VERSION='v1.0.3'

def download(path,cn):
    cdn=f'https://cdn.jsdelivr.net/gh/{REPO}@{VERSION}/{path}'
    raw=f'https://raw.githubusercontent.com/{REPO}/{VERSION}/{path}'
    urls=[cdn,raw] if cn else [raw,cdn]
    for url in urls:
        try:
            with urllib.request.urlopen(urllib.request.Request(url,headers={'User-Agent':'video-script-pro-installer/1.0'}),timeout=15) as r:
                return r.read()
        except Exception:pass
    raise ValueError(f'下载失败：{path}。请获取完整 ZIP，解压后离线执行本安装器；不需要 Git。')

def install(skills_dir,cn=False):
    root=Path(__file__).resolve().parent
    local=(root/'manifest.json').is_file() and (root/'SKILL.md').is_file()
    manifest=json.loads((root/'manifest.json').read_bytes() if local else download('manifest.json',cn))
    if manifest.get('version')!=VERSION:raise ValueError('版本清单不匹配')
    entries=manifest['files']
    for name in entries:
        p=PurePosixPath(name)
        if p.is_absolute() or '..' in p.parts or '\\' in name or ':' in name:
            raise ValueError('清单含非法路径')
    dest=Path(skills_dir).expanduser().resolve()/'video-script-pro'
    if dest.exists():raise ValueError(f'已存在 {dest}；请先备份并移开旧版本，不自动覆盖')
    dest.parent.mkdir(parents=True,exist_ok=True)
    with tempfile.TemporaryDirectory(prefix='.video-script-pro-',dir=dest.parent) as tmp:
        stage=Path(tmp)/'video-script-pro';stage.mkdir()
        def fetch(item):
            name,expected=item
            content=(root/name).read_bytes() if local else download(name,cn)
            if hashlib.sha256(content).hexdigest()!=expected:raise ValueError(f'文件校验失败：{name}')
            target=stage/name;target.parent.mkdir(parents=True,exist_ok=True);target.write_bytes(content)
        with ThreadPoolExecutor(max_workers=4) as pool:list(pool.map(fetch,entries.items()))
        (stage/'manifest.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8')
        stage.rename(dest)
    return {'ok':True,'path':str(dest),'files':len(entries),'source':'local' if local else 'online','next':f'python "{dest / "scripts/bootstrap.py"}" --install'+(' --cn' if cn else '')}

if __name__=='__main__':
    p=argparse.ArgumentParser(description=__doc__);p.add_argument('--skills-dir',required=True,help='当前平台实际 skills 目录');p.add_argument('--cn',action='store_true');a=p.parse_args()
    try:print(json.dumps(install(a.skills_dir,a.cn),ensure_ascii=False))
    except Exception as ex:print(str(ex),file=sys.stderr);sys.exit(1)
