from fastapi import APIRouter, HTTPException, status

from src.core.db import SessionDep
from src.core.deps import CurrentUserDep
from src.core.encryption import encrypt
from src.services.notification_service import send_test_email
from src.group_settings.repo import GroupConfigRepoDep
from src.group_settings.schemas import GroupSettingsMeta, GroupSettingsUpdate, LogEntrySchema
from src.services.google_groups import check_user_in_group, is_group_admin
from src.services.logging_service import log_action

router = APIRouter(prefix="/settings", tags=["settings"])


async def _resolve_admin_group_config(
    user_email: str,
    group_config_repo: GroupConfigRepoDep,
    is_super_admin: bool = False,
    target_group_email: str | None = None,
):
    """
    Find the GroupConfig for which the current user is an admin.
    If is_super_admin=True and target_group_email is provided, allows direct access.
    """
    if is_super_admin and target_group_email:
        config = await group_config_repo.get_by_group_email(target_group_email)
        if config:
            return config

    all_configs = await group_config_repo.get_all()
    for config in all_configs:
        if check_user_in_group(user_email, config) and is_group_admin(user_email, config):
            return config

    # If super-admin but no specific group found/in group, just return the first if available
    if is_super_admin and all_configs:
        return all_configs[0]

    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail="Access denied. Group admin or Super-admin rights required.",
    )


@router.get("", response_model=GroupSettingsMeta)
async def get_settings(
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
    group_email: str | None = None,
) -> GroupSettingsMeta:
    """Return metadata about the current group's configuration (no secrets)."""
    config = await _resolve_admin_group_config(
        current_user.email,
        group_config_repo,
        is_super_admin=current_user.is_admin,
        target_group_email=group_email,
    )
    return GroupSettingsMeta(
        id=config.id,
        group_email=config.group_email,
        google_admin_email=config.google_admin_email,
        has_campflow_token=bool(config.campflow_api_token_enc),
        has_service_account=bool(config.service_account_json_enc),
        has_email_password=bool(config.email_password_enc),
        email_account=config.email_account,
        pdf_filename=config.pdf_filename,
        imap_server=config.imap_server,
        imap_port=config.imap_port,
        smtp_server=config.smtp_server,
        smtp_port=config.smtp_port,
        auto_mail_recipient=config.auto_mail_recipient,
        updated_at=config.updated_at,
    )


@router.post("", response_model=GroupSettingsMeta)
async def update_settings(
    payload: GroupSettingsUpdate,
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
    session: SessionDep,
) -> GroupSettingsMeta:
    """Update one or more credentials for the admin's group. Secrets are encrypted before storage."""
    config = await _resolve_admin_group_config(
        current_user.email,
        group_config_repo,
        is_super_admin=current_user.is_admin,
        target_group_email=payload.group_email,
    )

    token_enc = encrypt(payload.campflow_api_token) if payload.campflow_api_token else None
    sa_enc = encrypt(payload.service_account_json) if payload.service_account_json else None
    email_pass_enc = encrypt(payload.email_password) if payload.email_password else None

    updated = await group_config_repo.upsert(
        group_email=config.group_email,
        campflow_api_token_enc=token_enc,
        service_account_json_enc=sa_enc,
        google_admin_email=payload.google_admin_email,
        email_account=payload.email_account,
        email_password_enc=email_pass_enc,
        pdf_filename=payload.pdf_filename,
        imap_server=payload.imap_server,
        imap_port=payload.imap_port,
        smtp_server=payload.smtp_server,
        smtp_port=payload.smtp_port,
        auto_mail_recipient=payload.auto_mail_recipient,
    )

    # Audit Log
    await log_action(
        session=session,
        group_email=updated.group_email,
        user_email=current_user.email,
        action="UPDATE_SETTINGS",
        details="Updated group configuration settings."
    )

    # If email settings were updated, try to send a test email to the CURRENT USER
    if payload.email_account or payload.email_password or payload.smtp_server:
        from src.services.notification_service import send_test_email
        try:
            await send_test_email(session, updated, override_recipient=current_user.email)
        except Exception as e:
            # Log the error but don't fail the whole request if only the test email failed
            import logging
            logging.getLogger(__name__).error(f"Test email to user failed: {e}")
            pass

    # If auto-recipient was updated, try to send a test email to THAT RECIPIENT
    if payload.auto_mail_recipient:
        from src.services.notification_service import send_test_email
        try:
            await send_test_email(session, updated, override_recipient=payload.auto_mail_recipient)
        except Exception as e:
            import logging
            logging.getLogger(__name__).error(f"Test email to auto-recipient failed: {e}")
            pass

    return GroupSettingsMeta(
        id=updated.id,
        group_email=updated.group_email,
        google_admin_email=updated.google_admin_email,
        has_campflow_token=bool(updated.campflow_api_token_enc),
        has_service_account=bool(updated.service_account_json_enc),
        has_email_password=bool(updated.email_password_enc),
        email_account=updated.email_account,
        pdf_filename=updated.pdf_filename,
        imap_server=updated.imap_server,
        imap_port=updated.imap_port,
        smtp_server=updated.smtp_server,
        smtp_port=updated.smtp_port,
        auto_mail_recipient=updated.auto_mail_recipient,
        updated_at=updated.updated_at,
    )


@router.get("/logs", response_model=list[LogEntrySchema])
async def get_logs(
    current_user: CurrentUserDep,
    group_config_repo: GroupConfigRepoDep,
    group_email: str | None = None,
) -> list[LogEntrySchema]:
    """Return recent audit logs for the group."""
    config = await _resolve_admin_group_config(
        current_user.email,
        group_config_repo,
        is_super_admin=current_user.is_admin,
        target_group_email=group_email,
    )
    logs = await group_config_repo.get_logs(config.group_email)
    return [LogEntrySchema.from_orm(l) for l in logs]
