import json
import os
from pathlib import Path

import win32crypt


CREDENTIALS_PATH = Path(os.getenv(
    'LOCALAPPDATA',
    Path.home() / 'AppData' / 'Local',
)) / 'TibiaPilotNG' / 'credentials.bin'


def save_credentials(account: str, password: str) -> None:
    account = account.strip()
    if len(account) > 254:
        raise ValueError('Account name is too long.')
    if not password or len(password) > 1024:
        raise ValueError('A password is required.')
    payload = json.dumps(
        {'account': account, 'password': password},
        ensure_ascii=False,
    ).encode('utf-8')
    encrypted = win32crypt.CryptProtectData(
        payload, 'TibiaPilotNG', None, None, None, 0,
    )
    CREDENTIALS_PATH.parent.mkdir(parents=True, exist_ok=True)
    temporary = CREDENTIALS_PATH.with_suffix('.tmp')
    temporary.write_bytes(encrypted)
    os.replace(temporary, CREDENTIALS_PATH)


def load_credentials():
    if not CREDENTIALS_PATH.exists():
        return None
    decrypted = win32crypt.CryptUnprotectData(
        CREDENTIALS_PATH.read_bytes(), None, None, None, 0,
    )[1]
    credentials = json.loads(decrypted.decode('utf-8'))
    account = credentials.get('account')
    password = credentials.get('password')
    if not isinstance(account, str) or not isinstance(password, str) or not password:
        raise ValueError('Stored Tibia credentials are invalid.')
    return {'account': account, 'password': password}
