"""Employees plugin main class.

Blueprint-only plugin: a read-only employee directory lookup over a separate HR
database. No model (the directory is an external DB) and no AssetType. The
connection helper (employee_connection) stays core infrastructure in shopdb.api,
shared with search and the notifications shopfloor feed.
"""

import json
import logging
from pathlib import Path
from typing import List, Dict, Optional, Type

from flask import Flask, Blueprint

from shopdb.plugins.base import BasePlugin, PluginMeta

from .api import employees_bp
from .models import DirectoryEmployee

logger = logging.getLogger(__name__)


class EmployeesPlugin(BasePlugin):
    """Employees plugin - read-only HR directory lookup."""

    def __init__(self):
        self._manifest = self._load_manifest()

    def _load_manifest(self) -> Dict:
        """Load plugin manifest from JSON file."""
        manifest_path = Path(__file__).parent / 'manifest.json'
        if manifest_path.exists():
            with open(manifest_path, 'r') as f:
                return json.load(f)
        return {}

    @property
    def meta(self) -> PluginMeta:
        """Return plugin metadata."""
        return PluginMeta(
            name=self._manifest.get('name', 'employees'),
            version=self._manifest.get('version', '1.0.0'),
            description=self._manifest.get(
                'description',
                'Read-only employee directory lookup'
            ),
            author=self._manifest.get('author', 'ShopDB Team'),
            dependencies=self._manifest.get('dependencies', []),
            core_version=self._manifest.get('core_version', '>=0.1.0,<1.0.0'),
            api_prefix=self._manifest.get('api_prefix', '/api/employees'),
        )

    def get_blueprint(self) -> Optional[Blueprint]:
        """Return Flask Blueprint with API routes."""
        return employees_bp

    def get_models(self) -> List[Type]:
        """Self-hosted directory table (used when directory_mode=selfhosted).
        External mode reads a separate DB via employee_connection instead."""
        return [DirectoryEmployee]

    def get_provisioning_note(self) -> Optional[Dict]:
        return {
            'mode_setting': 'employee_directory_mode',
            'tables': ['directoryemployees'],
            'note': ('Enabling this in self-hosted mode creates a '
                     '"directoryemployees" table in the shopdb database (SSO, '
                     'First_Name, Last_Name, Team, Role, Picture). It is '
                     'referenced across the site: employee search, notification '
                     'recognition (name + photo on the shopfloor/lobby displays), '
                     'and USB check-in/out name resolution. Manage people under '
                     'Settings > Employee Directory, or point at an existing HR '
                     'database instead (external mode).'),
            'docs': 'plugins/employees/README.md',
        }

    def get_config_schema(self) -> List[Dict]:
        """Employee directory DB connection. Host/name/user are settings the
        wizard can edit; the password stays in .env (emitted, not stored)."""
        return [
            {'key': 'employee_photo_base_url', 'label': 'Photo base URL',
             'type': 'text', 'secret': False,
             'help': 'Where external HR relative Picture paths resolve, e.g. '
                     'https://host/EmployeeDBAPP/images/. Blank = this '
                     'site\'s /static/employees/.'},
            {'key': 'employee_db_host', 'label': 'Employee DB host', 'type': 'text',
             'secret': False, 'default': 'localhost',
             'help': 'This DB must expose an "employees" table or view with columns '
                     'SSO, First_Name, Last_Name, Team, Role, Picture. '
                     'See plugins/employees/README.md.'},
            {'key': 'employee_db_name', 'label': 'Employee DB name', 'type': 'text',
             'secret': False, 'default': 'wjf_employees'},
            {'key': 'employee_db_user', 'label': 'Employee DB user', 'type': 'text',
             'secret': False},
            {'key': 'employee_db_password', 'label': 'Employee DB password', 'type': 'password',
             'secret': True, 'envvar': 'EMPLOYEE_DB_PASSWORD',
             'help': 'Stored in .env, not the database. The wizard shows the line to paste.'},
        ]

    def init_app(self, app: Flask, db_instance) -> None:
        """Initialize plugin with Flask app."""
        logger.info(f"Employees plugin initialized (v{self.meta.version})")
