# -*- coding: utf-8 -*-
from __future__ import annotations
import json
from pprint import pprint
from typing import Any

def print_inf(data: dict[str, Any], *, mode: str='pprint') -> None:
    if mode=='json': print(json.dumps(data, ensure_ascii=False, indent=2))
    elif mode=='pprint': pprint(data, width=120, sort_dicts=False)
    else: raise ValueError(f'Unknown print mode: {mode!r}')

def crystal_inf_to_text(data: dict[str, Any]) -> str:
    lines=[]; comp=data.get('composition',{}); lat=data.get('lattice',{}); den=data.get('density',{}); spg=data.get('spacegroup',{})
    lines += [f"Formula          : {comp.get('formula','')}", f"Reduced formula  : {comp.get('reduced_formula','')}",
              f"Sites            : {data.get('site_info',{}).get('n_sites','')}", f"Volume [A^3]     : {lat.get('volume','')}",
              f"Density [g/cm^3] : {den.get('mass_density_g_cm3','')}", '', 'Lattice',
              f"  a, b, c        : {lat.get('a','')}, {lat.get('b','')}, {lat.get('c','')}",
              f"  alpha,beta,gamma: {lat.get('alpha','')}, {lat.get('beta','')}, {lat.get('gamma','')}"]
    if spg:
        lines += ['', 'Space group']
        if spg.get('ok') is False: lines.append(f"  Failed         : {spg.get('error','')}")
        else: lines += [f"  Symbol         : {spg.get('symbol','')}", f"  Number         : {spg.get('number','')}", f"  Crystal system : {spg.get('crystal_system','')}"]
    sites=data.get('site_info',{}).get('sites',[])
    if sites:
        lines += ['', 'Sites', '  #    species                 frac_x        frac_y        frac_z']
        for s in sites:
            x,y,z=s.get('frac_coords',['','','']); lines.append(f"  {s.get('index',0):4d} {s.get('species_string',''):22s} {float(x):12.7f} {float(y):12.7f} {float(z):12.7f}")
    return '\n'.join(lines)

def print_crystal_inf(data: dict[str, Any]) -> None:
    print(crystal_inf_to_text(data))
