use axum::Router;
use uuid::Uuid;

use erp_core::error::AppResult;
use erp_core::events::EventBus;
use erp_core::module::{ErpModule, PermissionDescriptor};

use crate::handler::{auth_handler, org_handler, role_handler, user_handler};

/// Auth module implementing the `ErpModule` trait.
///
/// Manages identity, authentication, and user CRUD within the ERP platform.
/// This module has no dependencies on other business modules.
pub struct AuthModule;

impl AuthModule {
    pub fn new() -> Self {
        Self
    }

    /// Build public (unauthenticated) routes for the auth module.
    ///
    /// These routes do not require a valid JWT token.
    /// The caller wraps this into whatever state type the application uses.
    pub fn public_routes<S>() -> Router<S>
    where
        crate::auth_state::AuthState: axum::extract::FromRef<S>,
        S: Clone + Send + Sync + 'static,
    {
        Router::new()
            .route("/auth/login", axum::routing::post(auth_handler::login))
    }

    /// Refresh token routes — public but with higher rate limit (30/min vs 5/min for login).
    pub fn refresh_routes<S>() -> Router<S>
    where
        crate::auth_state::AuthState: axum::extract::FromRef<S>,
        S: Clone + Send + Sync + 'static,
    {
        Router::new().route("/auth/refresh", axum::routing::post(auth_handler::refresh))
    }

    /// Build protected (authenticated) routes for the auth module.
    ///
    /// These routes require a valid JWT token, verified by the middleware layer.
    /// The caller wraps this into whatever state type the application uses.
    pub fn protected_routes<S>() -> Router<S>
    where
        crate::auth_state::AuthState: axum::extract::FromRef<S>,
        S: Clone + Send + Sync + 'static,
    {
        Router::new()
            .route("/auth/logout", axum::routing::post(auth_handler::logout))
            .route(
                "/auth/change-password",
                axum::routing::post(auth_handler::change_password),
            )
            .route(
                "/users",
                axum::routing::get(user_handler::list_users).post(user_handler::create_user),
            )
            .route(
                "/users/{id}",
                axum::routing::get(user_handler::get_user)
                    .put(user_handler::update_user)
                    .delete(user_handler::delete_user),
            )
            .route(
                "/users/{id}/roles",
                axum::routing::post(user_handler::assign_roles),
            )
            .route(
                "/users/{id}/reset-password",
                axum::routing::post(user_handler::reset_password),
            )
            .route(
                "/roles",
                axum::routing::get(role_handler::list_roles).post(role_handler::create_role),
            )
            // 精确匹配 /roles/permissions，必须在 /roles/{id} 之前注册
            .route(
                "/roles/permissions",
                axum::routing::get(role_handler::list_permissions),
            )
            .route(
                "/roles/{id}",
                axum::routing::get(role_handler::get_role)
                    .put(role_handler::update_role)
                    .delete(role_handler::delete_role),
            )
            .route(
                "/roles/{id}/permissions",
                axum::routing::get(role_handler::get_role_permissions)
                    .post(role_handler::assign_permissions),
            )
            .route(
                "/permissions",
                axum::routing::get(role_handler::list_permissions),
            )
            // Organization routes
            .route(
                "/organizations",
                axum::routing::get(org_handler::list_organizations)
                    .post(org_handler::create_organization),
            )
            .route(
                "/organizations/{id}",
                axum::routing::put(org_handler::update_organization)
                    .delete(org_handler::delete_organization),
            )
            // Department routes (nested under organization)
            .route(
                "/organizations/{org_id}/departments",
                axum::routing::get(org_handler::list_departments)
                    .post(org_handler::create_department),
            )
            .route(
                "/departments/{id}",
                axum::routing::put(org_handler::update_department)
                    .delete(org_handler::delete_department),
            )
            // Position routes (nested under department)
            .route(
                "/departments/{dept_id}/positions",
                axum::routing::get(org_handler::list_positions).post(org_handler::create_position),
            )
            .route(
                "/positions/{id}",
                axum::routing::put(org_handler::update_position)
                    .delete(org_handler::delete_position),
            )
    }
}

impl Default for AuthModule {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait::async_trait]
impl ErpModule for AuthModule {
    fn name(&self) -> &str {
        "auth"
    }

    fn version(&self) -> &str {
        env!("CARGO_PKG_VERSION")
    }

    fn dependencies(&self) -> Vec<&str> {
        // Auth is a foundational module with no business-module dependencies.
        vec![]
    }

    fn register_event_handlers(&self, _bus: &EventBus) {
        // Auth 模块暂无跨模块事件订阅需求
    }

    async fn on_tenant_created(
        &self,
        tenant_id: Uuid,
        db: &sea_orm::DatabaseConnection,
        _event_bus: &EventBus,
    ) -> AppResult<()> {
        let password = std::env::var("ERP__SUPER_ADMIN_PASSWORD").map_err(|_| {
            tracing::error!("环境变量 ERP__SUPER_ADMIN_PASSWORD 未设置，无法初始化租户认证");
            erp_core::error::AppError::Internal("ERP__SUPER_ADMIN_PASSWORD 未设置".to_string())
        })?;
        crate::service::seed::seed_tenant_auth(db, tenant_id, &password)
            .await
            .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?;
        tracing::info!(tenant_id = %tenant_id, "Tenant auth initialized");
        Ok(())
    }

    async fn on_tenant_deleted(
        &self,
        tenant_id: Uuid,
        db: &sea_orm::DatabaseConnection,
    ) -> AppResult<()> {
        use chrono::Utc;
        use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};

        let now = Utc::now();

        // 软删除该租户下所有用户
        let users = crate::entity::user::Entity::find()
            .filter(crate::entity::user::Column::TenantId.eq(tenant_id))
            .filter(crate::entity::user::Column::DeletedAt.is_null())
            .all(db)
            .await
            .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?;

        for user_model in users {
            let current_version = user_model.version;
            let active: crate::entity::user::ActiveModel = user_model.into();
            let mut to_update: crate::entity::user::ActiveModel = active;
            to_update.deleted_at = Set(Some(now));
            to_update.updated_at = Set(now);
            to_update.version = Set(current_version + 1);
            let _ = to_update
                .update(db)
                .await
                .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?;
        }

        tracing::info!(tenant_id = %tenant_id, "Tenant users soft-deleted");
        Ok(())
    }

    fn permissions(&self) -> Vec<PermissionDescriptor> {
        vec![
            PermissionDescriptor {
                code: "user.list".into(),
                name: "查看用户列表".into(),
                description: "查看用户列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "user.create".into(),
                name: "创建用户".into(),
                description: "创建新用户".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "user.read".into(),
                name: "查看用户详情".into(),
                description: "查看用户信息".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "user.update".into(),
                name: "编辑用户".into(),
                description: "编辑用户信息".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "user.delete".into(),
                name: "删除用户".into(),
                description: "软删除用户".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "user.reset-password".into(),
                name: "重置用户密码".into(),
                description: "管理员重置指定用户密码".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "role.list".into(),
                name: "查看角色列表".into(),
                description: "查看角色列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "role.create".into(),
                name: "创建角色".into(),
                description: "创建新角色".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "role.read".into(),
                name: "查看角色详情".into(),
                description: "查看角色信息".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "role.update".into(),
                name: "编辑角色".into(),
                description: "编辑角色".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "role.delete".into(),
                name: "删除角色".into(),
                description: "删除角色".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "permission.list".into(),
                name: "查看权限".into(),
                description: "查看权限列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "organization.list".into(),
                name: "查看组织列表".into(),
                description: "查看组织列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "organization.create".into(),
                name: "创建组织".into(),
                description: "创建组织".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "organization.update".into(),
                name: "编辑组织".into(),
                description: "编辑组织".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "organization.delete".into(),
                name: "删除组织".into(),
                description: "删除组织".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "department.list".into(),
                name: "查看部门列表".into(),
                description: "查看部门列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "department.create".into(),
                name: "创建部门".into(),
                description: "创建部门".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "department.update".into(),
                name: "编辑部门".into(),
                description: "编辑部门".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "department.delete".into(),
                name: "删除部门".into(),
                description: "删除部门".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "position.list".into(),
                name: "查看岗位列表".into(),
                description: "查看岗位列表".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "position.create".into(),
                name: "创建岗位".into(),
                description: "创建岗位".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "position.update".into(),
                name: "编辑岗位".into(),
                description: "编辑岗位".into(),
                module: "auth".into(),
            },
            PermissionDescriptor {
                code: "position.delete".into(),
                name: "删除岗位".into(),
                description: "删除岗位".into(),
                module: "auth".into(),
            },
        ]
    }

    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}
