#!/usr/bin/env python3
"""Utwórz nowy, samodzielny projekt bez nadpisywania plików i bez publikacji."""
import argparse
from html import escape
from html.parser import HTMLParser
from pathlib import Path
import re
import shutil
import tempfile

ROOT = Path(__file__).resolve().parents[1]
VOID = {'area','base','br','col','embed','hr','img','input','link','meta','param','source','track','wbr'}

class Standalone(HTMLParser):
    def __init__(self):
        super().__init__(convert_charrefs=False)
        self.output = []
        self.depth = 0
        self.resources = set()
    def handle_starttag(self, tag, attrs):
        if self.depth:
            if tag not in VOID: self.depth += 1
            return
        if any(k == 'data-template-tools' for k,v in attrs):
            self.depth = 0 if tag in VOID else 1
            return
        result = []
        for k,v in attrs:
            if v and k in ('href','src') and v.startswith('../'):
                v = v[3:]
            if v and ((tag == 'link' and k == 'href') or (tag in ('img','script') and k == 'src')) and not v.startswith(('https:','http:','data:')):
                self.resources.add(v)
            result.append(k if v is None else f'{k}="{escape(v, quote=True)}"')
        self.output.append('<'+tag+(' '+ ' '.join(result) if result else '')+'>')
    def handle_endtag(self, tag):
        if self.depth:
            self.depth -= 1
        else: self.output.append('</'+tag+'>')
    def handle_data(self, text):
        if not self.depth: self.output.append(text)
    def handle_entityref(self, name):
        if not self.depth: self.output.append('&'+name+';')
    def handle_charref(self, name):
        if not self.depth: self.output.append('&#'+name+';')
    def handle_decl(self, decl):
        if not self.depth: self.output.append('<!'+decl+'>')
    def handle_comment(self, text):
        if not self.depth: self.output.append('<!--'+text+'-->')

def main():
    cli = argparse.ArgumentParser(description=__doc__)
    cli.add_argument('kind', choices=['report','landing'])
    cli.add_argument('destination', type=Path, help='Nowy, nieistniejący folder. Rodzic musi istnieć.')
    args = cli.parse_args()
    destination = args.destination.expanduser().absolute()
    if destination.exists(): cli.error('Folder docelowy już istnieje. Wybierz nowy folder; nic nie nadpisano.')
    if not destination.parent.is_dir(): cli.error('Folder nadrzędny nie istnieje.')
    parser = Standalone()
    parser.feed((ROOT/'templates'/f'{args.kind}.html').read_text())
    if parser.depth: raise ValueError('Niezamknięty kontener narzędzi szablonu.')
    # Collect only used resources, not client screenshots or unused source assets.
    resources = {}
    def collect(name, source=None):
        relative = Path(name)
        if relative.is_absolute() or '..' in relative.parts: raise ValueError('Niedozwolona ścieżka zasobu: '+name)
        if name in resources: return
        source = source or ROOT/relative
        if not source.is_file(): raise FileNotFoundError(source)
        resources[name] = source
        if source.suffix == '.css':
            for ref in re.findall(r'url\([\s\'"]*([^\)\'"\s]+)',source.read_text()):
                if ref.startswith(('data:','https:','http:')): raise ValueError('Szablon ma zewnętrzny zasób: '+ref)
                collect(str(relative.parent/ref),source.parent/ref)
    for name in parser.resources:
        source = ROOT/'templates'/name if name == f'{args.kind}.css' else ROOT/name
        collect(name,source)
    # Keep the final responsive layer with each standalone template copy.
    collect('mobile-readability.css')
    with tempfile.TemporaryDirectory(prefix='.dealyo-template-',dir=destination.parent) as temporary:
        stage = Path(temporary)/'project'
        stage.mkdir()
        (stage/'index.html').write_text(''.join(parser.output))
        for name,source in resources.items():
            target = stage/name
            target.parent.mkdir(parents=True,exist_ok=True)
            shutil.copy2(source,target)
        shutil.copy2(ROOT/'templates'/f'{args.kind.upper()}.md',stage/'TEMPLATE.md')
        reference = 'https://icd-audyt-konta-2026-10-18.dealyocode.workers.dev/' if args.kind == 'report' else 'https://audyt.dealyo.io/'
        (stage/'README.md').write_text(f'''# Dealyo — nowy projekt {args.kind}\n\nOtwórz index.html. Edytuj treść w HTML i układ w {args.kind}.css.\n\nTo kopia roboczego szablonu v0.3, nie gotowa publikacja. Uzupełnij pola w nawiasach kwadratowych, sprawdź źródła danych i usuń moduły, których nie potrzebujesz. Formularz demonstracyjny niczego nie wysyła. Wykres bez danych pozostaje pusty.\n\nReferencja: {reference}\n\nZachowaj pomarańcz #FE4A23, oryginalne logo i proste narożniki. TEMPLATE.md opisuje pola szablonu; jego odwołania do biblioteki źródłowej dotyczą oryginalnego katalogu design-system. Po uzupełnieniu sprawdź telefon, klawiaturę, odnośniki i wszystkie działania. Skrypt nie publikuje strony.\n''')
        # mkdir is exclusive; protects against a destination created during preparation.
        destination.mkdir()
        try:
            for item in stage.iterdir(): shutil.move(str(item),destination/item.name)
        except Exception:
            # Preserve partial output for diagnosis; never remove user's files.
            raise
    print('Utworzono: '+str(destination/'index.html'))

if __name__ == '__main__': main()
