import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { z } from '@hono/zod-openapi';
import { In } from 'typeorm';
import { authMiddleware } from '@d8d/auth-module';
import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
import { AuthContext } from '@d8d/shared-types';
import { RoleService } from '../services';
import { RoleSchema } from '../schemas/role.schema';
import { PERMISSIONS } from '../constants';

// 定义 Schema
const PermissionListSchema = z.object({
  permissions: z.array(z.string()).openapi({
    description: '权限列表',
    example: ['advertisement:view', 'advertisement:create']
  })
}).openapi('PermissionList');

const UserPermissionResponseSchema = z.object({
  permissions: z.array(z.string()).openapi({
    description: '用户权限列表'
  })
}).openapi('UserPermissionResponse');

const RoleListResponseSchema = z.object({
  roles: z.array(RoleSchema).openapi({
    description: '角色列表'
  })
}).openapi('RoleListResponse');

const RolePermissionUpdateSchema = z.object({
  permissions: z.array(z.string()).openapi({
    description: '新的权限列表'
  })
}).openapi('RolePermissionUpdate');

const UserRoleResponseSchema = z.object({
  roles: z.array(RoleSchema).openapi({
    description: '用户角色列表'
  })
}).openapi('UserRoleResponse');

const UserRoleUpdateSchema = z.object({
  roleIds: z.array(z.number()).openapi({
    description: '角色ID列表'
  })
}).openapi('UserRoleUpdate');

// 1. GET /api/user/permissions - 获取当前用户权限列表
const getUserPermissionsRoute = createRoute({
  method: 'get',
  path: '/user/permissions',
  middleware: [authMiddleware],
  responses: {
    200: {
      description: '获取当前用户权限列表成功',
      content: {
        'application/json': {
          schema: UserPermissionResponseSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 2. GET /api/roles - 获取角色列表（带权限）
const getRolesRoute = createRoute({
  method: 'get',
  path: '/roles',
  middleware: [authMiddleware],
  responses: {
    200: {
      description: '获取角色列表成功',
      content: {
        'application/json': {
          schema: RoleListResponseSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 3. PUT /api/roles/{id}/permissions - 更新角色权限
const updateRolePermissionsRoute = createRoute({
  method: 'put',
  path: '/roles/{id}/permissions',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.string().openapi({
        param: {
          name: 'id',
          in: 'path'
        },
        description: '角色ID'
      })
    }),
    body: {
      content: {
        'application/json': {
          schema: RolePermissionUpdateSchema
        }
      }
    }
  },
  responses: {
    200: {
      description: '更新角色权限成功',
      content: {
        'application/json': {
          schema: RoleSchema
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '角色不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 4. GET /api/users/{id}/roles - 获取用户角色
const getUserRolesRoute = createRoute({
  method: 'get',
  path: '/users/{id}/roles',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.string().openapi({
        param: {
          name: 'id',
          in: 'path'
        },
        description: '用户ID'
      })
    })
  },
  responses: {
    200: {
      description: '获取用户角色成功',
      content: {
        'application/json': {
          schema: UserRoleResponseSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '用户不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 5. PUT /api/users/{id}/roles - 更新用户角色
const updateUserRolesRoute = createRoute({
  method: 'put',
  path: '/users/{id}/roles',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.string().openapi({
        param: {
          name: 'id',
          in: 'path'
        },
        description: '用户ID'
      })
    }),
    body: {
      content: {
        'application/json': {
          schema: UserRoleUpdateSchema
        }
      }
    }
  },
  responses: {
    200: {
      description: '更新用户角色成功',
      content: {
        'application/json': {
          schema: UserRoleResponseSchema
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '用户或角色不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 创建路由应用
const app = new OpenAPIHono<AuthContext>();

// 1. 获取当前用户权限列表
app.openapi(getUserPermissionsRoute, async (c) => {
  try {
    const user = c.get('user');
    const service = new RoleService(AppDataSource);
    const permissions = await service.getUserPermissions(user.id, user.tenantId);

    const responseData = await parseWithAwait(UserPermissionResponseSchema, { permissions });
    return c.json(responseData, 200);
  } catch (error) {
    console.error('获取用户权限列表失败:', error);
    return c.json(
      { code: 500, message: error instanceof Error ? error.message : '获取用户权限列表失败' },
      500
    );
  }
});

// 2. 获取角色列表
app.openapi(getRolesRoute, async (c) => {
  try {
    const user = c.get('user');
    const service = new RoleService(AppDataSource);
    const roles = await service.repository.find({
      where: { tenantId: user.tenantId }
    });

    const responseData = await parseWithAwait(RoleListResponseSchema, { roles });
    return c.json(responseData, 200);
  } catch (error) {
    console.error('获取角色列表失败:', error);
    return c.json(
      { code: 500, message: error instanceof Error ? error.message : '获取角色列表失败' },
      500
    );
  }
});

// 3. 更新角色权限
app.openapi(updateRolePermissionsRoute, async (c) => {
  try {
    const { id } = c.req.valid('param');
    const { permissions } = c.req.valid('json');
    const user = c.get('user');

    const service = new RoleService(AppDataSource);
    const role = await service.repository.findOne({
      where: { id: parseInt(id), tenantId: user.tenantId }
    });

    if (!role) {
      return c.json({ code: 404, message: '角色不存在' }, 404);
    }

    // 更新权限
    role.permissions = permissions;
    await service.repository.save(role);

    const responseData = await parseWithAwait(RoleSchema, role);
    return c.json(responseData, 200);
  } catch (error) {
    console.error('更新角色权限失败:', error);
    return c.json(
      { code: 500, message: error instanceof Error ? error.message : '更新角色权限失败' },
      500
    );
  }
});

// 4. 获取用户角色
app.openapi(getUserRolesRoute, async (c) => {
  try {
    const { id } = c.req.valid('param');
    const user = c.get('user');

    const service = new RoleService(AppDataSource);
    const roles = await service.getUserRoles(parseInt(id), user.tenantId);

    const responseData = await parseWithAwait(UserRoleResponseSchema, { roles });
    return c.json(responseData, 200);
  } catch (error) {
    console.error('获取用户角色失败:', error);
    return c.json(
      { code: 500, message: error instanceof Error ? error.message : '获取用户角色失败' },
      500
    );
  }
});

// 5. 更新用户角色
app.openapi(updateUserRolesRoute, async (c) => {
  try {
    const { id } = c.req.valid('param');
    const { roleIds } = c.req.valid('json');
    const user = c.get('user');

    const service = new RoleService(AppDataSource);
    const targetUser = await service.userRepository.findOne({
      where: { id: parseInt(id) },
      relations: ['roles']
    });

    if (!targetUser) {
      return c.json({ code: 404, message: '用户不存在' }, 404);
    }

    // 获取所有角色（确保属于同一租户）
    const roles = await service.repository.find({
      where: {
        id: In(roleIds),
        tenantId: user.tenantId
      }
    });

    if (roles.length !== roleIds.length) {
      return c.json({ code: 404, message: '部分角色不存在或不属于当前租户' }, 404);
    }

    // 更新用户角色
    targetUser.roles = roles;
    await service.userRepository.save(targetUser);

    const responseData = await parseWithAwait(UserRoleResponseSchema, { roles });
    return c.json(responseData, 200);
  } catch (error) {
    console.error('更新用户角色失败:', error);
    return c.json(
      { code: 500, message: error instanceof Error ? error.message : '更新用户角色失败' },
      500
    );
  }
});

export default app;