from __future__ import annotations

import json

from core.exceptions import FileValidationError

MAX_FILE_SIZE_MB = 100
SUPPORTED_VERSIONS = {'1.0', '2.0'}
REQUIRED_FIELDS = {'document', 'styles', 'pages', 'fonts_used'}


class ExportValidator:
    """Validates idconvert_export.json before any parsing occurs."""

    def validate(self, content: bytes) -> dict:
        """Run all validation checks. Returns parsed dict on success.
        Raises FileValidationError on any failure.
        """
        # 1. File size
        size_mb = len(content) / (1024 * 1024)
        if size_mb > MAX_FILE_SIZE_MB:
            raise FileValidationError(
                f'File exceeds {MAX_FILE_SIZE_MB}MB limit.',
                'FILE_TOO_LARGE',
            )

        # 2. Valid JSON
        try:
            data = json.loads(content)
        except (json.JSONDecodeError, UnicodeDecodeError):
            raise FileValidationError(
                'This does not appear to be a valid IDexport file. '
                'Please run IDexport.jsx in InDesign and upload the '
                'idconvert_export.json file it produces.',
                'INVALID_JSON',
            )

        if not isinstance(data, dict):
            raise FileValidationError(
                'IDexport file has an unexpected format.',
                'INVALID_FORMAT',
            )

        # 3. Generator signature
        if data.get('generator') != 'IDexport':
            raise FileValidationError(
                'This JSON file was not produced by IDexport. '
                'Please run IDexport.jsx in InDesign to generate '
                'a compatible export file.',
                'WRONG_GENERATOR',
            )

        # 4. Version check
        if data.get('version') not in SUPPORTED_VERSIONS:
            raise FileValidationError(
                'This IDexport file was created with an incompatible version. '
                'Please download the latest IDexport.jsx from IDconvert.',
                'VERSION_MISMATCH',
            )

        # 5. Required top-level fields
        for f in REQUIRED_FIELDS:
            if f not in data:
                raise FileValidationError(
                    f'IDexport file is missing required field: {f}. '
                    'Please re-run IDexport.jsx and try again.',
                    'MISSING_FIELD',
                )

        # 6. Pages must be a non-empty list
        if not isinstance(data.get('pages'), list) or len(data['pages']) == 0:
            raise FileValidationError(
                'IDexport file contains no pages.',
                'NO_PAGES',
            )

        return data
