import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { z } from '@hono/zod-openapi';
import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
import { authMiddleware } from '@d8d/auth-module';
import { AuthContext } from '@d8d/shared-types';
import { DisabledPersonService } from '../services/disabled-person.service';
import {
  DisabledPersonSchema,
  CreateDisabledPersonSchema,
  UpdateDisabledPersonSchema,
  DeleteDisabledPersonSchema,
  PaginationQuerySchema,
  SearchDisabledPersonQuerySchema
} from '../schemas/disabled-person.schema';

// 创建残疾人路由 - 返回残疾人信息
const createDisabledPersonRoute = createRoute({
  method: 'post',
  path: '/createDisabledPerson',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: CreateDisabledPersonSchema }
      }
    }
  },
  responses: {
    200: {
      description: '残疾人创建成功',
      content: {
        'application/json': { schema: DisabledPersonSchema }
      }
    },
    400: {
      description: '参数错误或身份证号已存在',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '创建残疾人失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 删除残疾人路由 - 返回布尔值
const deleteDisabledPersonRoute = createRoute({
  method: 'post',
  path: '/deleteDisabledPerson',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: DeleteDisabledPersonSchema }
      }
    }
  },
  responses: {
    200: {
      description: '残疾人删除成功',
      content: {
        'application/json': {
          schema: z.object({
            success: z.boolean().openapi({ description: '是否成功' })
          })
        }
      }
    },
    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 updateDisabledPersonRoute = createRoute({
  method: 'post',
  path: '/updateDisabledPerson',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: UpdateDisabledPersonSchema }
      }
    }
  },
  responses: {
    200: {
      description: '残疾人更新成功',
      content: {
        'application/json': { schema: DisabledPersonSchema }
      }
    },
    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 getAllDisabledPersonsRoute = createRoute({
  method: 'get',
  path: '/getAllDisabledPersons',
  middleware: [authMiddleware],
  request: {
    query: SearchDisabledPersonQuerySchema
  },
  responses: {
    200: {
      description: '获取残疾人列表成功',
      content: {
        'application/json': {
          schema: z.object({
            data: z.array(DisabledPersonSchema).openapi({ description: '残疾人列表' }),
            total: z.number().int().openapi({ description: '总记录数' })
          })
        }
      }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '获取残疾人列表失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 搜索残疾人路由 - 按姓名、身份证号模糊搜索
const searchDisabledPersonsRoute = createRoute({
  method: 'get',
  path: '/searchDisabledPersons',
  middleware: [authMiddleware],
  request: {
    query: SearchDisabledPersonQuerySchema
  },
  responses: {
    200: {
      description: '搜索残疾人成功',
      content: {
        'application/json': {
          schema: z.object({
            data: z.array(DisabledPersonSchema).openapi({ description: '残疾人列表' }),
            total: z.number().int().openapi({ description: '总记录数' })
          })
        }
      }
    },
    400: {
      description: '搜索关键词不能为空',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '搜索残疾人失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 获取单个残疾人路由
const getDisabledPersonRoute = createRoute({
  method: 'get',
  path: '/getDisabledPerson/{id}',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.coerce.number().int().positive().openapi({
        param: { name: 'id', in: 'path' },
        example: 1,
        description: '残疾人ID'
      })
    })
  },
  responses: {
    200: {
      description: '获取残疾人详情成功',
      content: {
        'application/json': { schema: DisabledPersonSchema.nullable() }
      }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '获取残疾人详情失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 根据身份证号查询残疾人路由
const findByIdCardRoute = createRoute({
  method: 'get',
  path: '/findByIdCard/{idCard}',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      idCard: z.string().openapi({
        param: { name: 'idCard', in: 'path' },
        example: '110101199001011234',
        description: '身份证号码'
      })
    })
  },
  responses: {
    200: {
      description: '根据身份证号查询成功',
      content: {
        'application/json': { schema: DisabledPersonSchema.nullable() }
      }
    },
    400: {
      description: '身份证号格式错误',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '查询失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 批量创建残疾人路由
const batchCreateDisabledPersonsRoute = createRoute({
  method: 'post',
  path: '/batchCreateDisabledPersons',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': {
          schema: z.object({
            persons: z.array(CreateDisabledPersonSchema).openapi({
              description: '残疾人信息列表',
              example: [
                {
                  name: '张三',
                  idCard: '110101199001011234',
                  gender: 1,
                  birthDate: '1990-01-01',
                  disabilityType: '视力残疾',
                  disabilityLevel: '一级',
                  address: '北京市东城区'
                }
              ]
            })
          })
        }
      }
    }
  },
  responses: {
    200: {
      description: '批量创建成功',
      content: {
        'application/json': {
          schema: z.object({
            success: z.boolean().openapi({ description: '是否成功' }),
            createdCount: z.number().int().openapi({ description: '成功创建数量' }),
            failedItems: z.array(z.object({
              index: z.number().int().openapi({ description: '失败项索引' }),
              error: z.string().openapi({ description: '错误信息' })
            })).openapi({ description: '失败项列表' })
          })
        }
      }
    },
    400: {
      description: '参数错误或身份证号重复',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '批量创建失败',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

const app = new OpenAPIHono<AuthContext>()
  // 创建残疾人
  .openapi(createDisabledPersonRoute, async (c) => {
    try {
      const data = c.req.valid('json');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.create(data);

      return c.json(await parseWithAwait(DisabledPersonSchema, result), 200);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({
          code: 400,
          message: '参数错误',
          errors: error.issues
        }, 400);
      }

      // 处理身份证号重复错误
      if (error instanceof Error && error.message.includes('身份证号已存在')) {
        return c.json({
          code: 400,
          message: '身份证号已存在'
        }, 400);
      }

      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '创建残疾人失败'
      }, 500);
    }
  })
  // 删除残疾人
  .openapi(deleteDisabledPersonRoute, async (c) => {
    try {
      const { id } = c.req.valid('json');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const success = await disabledPersonService.delete(id);

      if (!success) {
        return c.json({ code: 404, message: '残疾人不存在' }, 404);
      }

      return c.json({ success }, 200);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({
          code: 400,
          message: '参数错误',
          errors: error.issues
        }, 400);
      }

      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '删除残疾人失败'
      }, 500);
    }
  })
  // 更新残疾人
  .openapi(updateDisabledPersonRoute, async (c) => {
    try {
      const data = c.req.valid('json');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.update(data.id, data);

      if (!result) {
        return c.json({ code: 404, message: '残疾人不存在' }, 404);
      }

      return c.json(await parseWithAwait(DisabledPersonSchema, result), 200);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({
          code: 400,
          message: '参数错误',
          errors: error.issues
        }, 400);
      }

      // 处理身份证号重复错误
      if (error instanceof Error && error.message.includes('身份证号已存在')) {
        return c.json({
          code: 400,
          message: '身份证号已存在'
        }, 400);
      }

      // 处理残疾人不存在错误
      if (error instanceof Error && error.message.includes('残疾人不存在')) {
        return c.json({
          code: 404,
          message: '残疾人不存在'
        }, 404);
      }

      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '更新残疾人失败'
      }, 500);
    }
  })
  // 获取所有残疾人
  .openapi(getAllDisabledPersonsRoute, async (c) => {
    try {
      const { keyword, bankNameId, cardType, disabilityType, disabilityLevel, province, skip, take } = c.req.valid('query');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.findAll({
        keyword,
        bankNameId,
        cardType,
        disabilityType,
        disabilityLevel,
        province,
        page: skip ? Math.floor(skip / (take || 10)) + 1 : 1,
        limit: take || 10
      });

      return c.json(result, 200);
    } catch (error) {
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取残疾人列表失败'
      }, 500);
    }
  })
  // 搜索残疾人
  .openapi(searchDisabledPersonsRoute, async (c) => {
    try {
      const { keyword, bankNameId, cardType, disabilityType, disabilityLevel, province, skip, take } = c.req.valid('query');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      // 使用 findAll 方法进行搜索，支持所有筛选参数
      const result = await disabledPersonService.findAll({
        keyword,
        bankNameId,
        cardType,
        disabilityType,
        disabilityLevel,
        province,
        page: skip ? Math.floor(skip / (take || 10)) + 1 : 1,
        limit: take || 10
      });

      return c.json(result, 200);
    } catch (error) {
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '搜索残疾人失败'
      }, 500);
    }
  })
  // 获取单个残疾人
  .openapi(getDisabledPersonRoute, async (c) => {
    try {
      const { id } = c.req.valid('param');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.findOne(id);

      if (!result) {
        return c.json(null, 200);
      }

      const validatedResult = await parseWithAwait(DisabledPersonSchema, result);
      return c.json(validatedResult, 200);
    } catch (error) {
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取残疾人详情失败'
      }, 500);
    }
  })
  // 根据身份证号查询
  .openapi(findByIdCardRoute, async (c) => {
    try {
      const { idCard } = c.req.valid('param');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.findByIdCard(idCard);

      if (!result) {
        return c.json(null, 200);
      }

      const validatedResult = await parseWithAwait(DisabledPersonSchema, result);
      return c.json(validatedResult, 200);
    } catch (error) {
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '根据身份证号查询失败'
      }, 500);
    }
  })
  // 批量创建残疾人
  .openapi(batchCreateDisabledPersonsRoute, async (c) => {
    try {
      const { persons } = c.req.valid('json');
      const disabledPersonService = new DisabledPersonService(AppDataSource);

      const result = await disabledPersonService.batchCreate(persons);

      return c.json(result, 200);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({
          code: 400,
          message: '参数错误',
          errors: error.issues
        }, 400);
      }

      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '批量创建残疾人失败'
      }, 500);
    }
  });

export default app;