import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { z } from '@hono/zod-openapi';
import { AreaServiceMt } from '../../modules/areas/area.service.mt';
import { AreaLevel } from '../../modules/areas/area.entity.mt';
import { AppDataSource } from '@d8d/shared-utils';
import { authMiddleware } from '@d8d/auth-module-mt';
import { AuthContext } from '@d8d/shared-types';

// 省份查询参数Schema（多租户）
const getProvincesSchema = z.object({
  page: z.coerce.number<number>().int().min(1).default(1).openapi({
    example: 1,
    description: '页码'
  }),
  pageSize: z.coerce.number<number>().int().min(1).max(100).default(50).openapi({
    example: 50,
    description: '每页数量'
  })
});

// 城市查询参数Schema（多租户）
const getCitiesSchema = z.object({
  provinceId: z.coerce.number<number>().int().positive('省份ID必须为正整数').openapi({
    example: 1,
    description: '省份ID'
  }),
  page: z.coerce.number<number>().int().min(1).default(1).openapi({
    example: 1,
    description: '页码'
  }),
  pageSize: z.coerce.number<number>().int().min(1).max(100).default(50).openapi({
    example: 50,
    description: '每页数量'
  })
});

// 区县查询参数Schema（多租户）
const getDistrictsSchema = z.object({
  cityId: z.coerce.number<number>().int().positive('城市ID必须为正整数').openapi({
    example: 34,
    description: '城市ID'
  }),
  page: z.coerce.number<number>().int().min(1).default(1).openapi({
    example: 1,
    description: '页码'
  }),
  pageSize: z.coerce.number<number>().int().min(1).max(100).default(50).openapi({
    example: 50,
    description: '每页数量'
  })
});

// 街道查询参数Schema（多租户）
const getTownsSchema = z.object({
  districtId: z.coerce.number<number>().int().positive('区县ID必须为正整数').openapi({
    example: 3401,
    description: '区县ID'
  }),
  page: z.coerce.number<number>().int().min(1).default(1).openapi({
    example: 1,
    description: '页码'
  }),
  pageSize: z.coerce.number<number>().int().min(1).max(100).default(50).openapi({
    example: 50,
    description: '每页数量'
  })
});

// 省市区响应Schema
const areaResponseSchema = z.object({
  id: z.number(),
  name: z.string(),
  code: z.string(),
  level: z.number(),
  parentId: z.number().nullable()
});

// 省份列表响应Schema
const provincesResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    provinces: z.array(areaResponseSchema),
    pagination: z.object({
      page: z.number(),
      pageSize: z.number(),
      total: z.number(),
      totalPages: z.number()
    })
  }),
  message: z.string()
});

// 城市列表响应Schema
const citiesResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    cities: z.array(areaResponseSchema),
    pagination: z.object({
      page: z.number(),
      pageSize: z.number(),
      total: z.number(),
      totalPages: z.number()
    })
  }),
  message: z.string()
});

// 区县列表响应Schema
const districtsResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    districts: z.array(areaResponseSchema),
    pagination: z.object({
      page: z.number(),
      pageSize: z.number(),
      total: z.number(),
      totalPages: z.number()
    })
  }),
  message: z.string()
});

// 街道列表响应Schema
const townsResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    towns: z.array(areaResponseSchema),
    pagination: z.object({
      page: z.number(),
      pageSize: z.number(),
      total: z.number(),
      totalPages: z.number()
    })
  }),
  message: z.string()
});

// 错误响应Schema
const errorSchema = z.object({
  code: z.number(),
  message: z.string(),
  errors: z.array(z.object({
    path: z.array(z.string()),
    message: z.string()
  })).optional()
});

// 创建省份查询路由（多租户）
const getProvincesRoute = createRoute({
  method: 'get',
  path: '/provinces',
  middleware: [ authMiddleware ],
  request: {
    query: getProvincesSchema
  },
  responses: {
    200: {
      description: '获取省份列表成功',
      content: {
        'application/json': { schema: provincesResponseSchema }
      }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: errorSchema } }
    },
    500: {
      description: '获取省份列表失败',
      content: { 'application/json': { schema: errorSchema } }
    }
  }
});

// 创建城市查询路由（多租户）
const getCitiesRoute = createRoute({
  method: 'get',
  path: '/cities',
  middleware: [ authMiddleware ],
  request: {
    query: getCitiesSchema
  },
  responses: {
    200: {
      description: '获取城市列表成功',
      content: {
        'application/json': { schema: citiesResponseSchema }
      }
    },
    400: {
      description: '参数错误',
      content: { 'application/json': { schema: errorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: errorSchema } }
    },
    500: {
      description: '获取城市列表失败',
      content: { 'application/json': { schema: errorSchema } }
    }
  }
});

// 创建区县查询路由（多租户）
const getDistrictsRoute = createRoute({
  method: 'get',
  path: '/districts',
  middleware: [ authMiddleware ],
  request: {
    query: getDistrictsSchema
  },
  responses: {
    200: {
      description: '获取区县列表成功',
      content: {
        'application/json': { schema: districtsResponseSchema }
      }
    },
    400: {
      description: '参数错误',
      content: { 'application/json': { schema: errorSchema } }
    },
    401: {
      description: '认证失败',
      content: { 'application/json': { schema: errorSchema } }
    },
    500: {
      description: '获取区县列表失败',
      content: { 'application/json': { schema: errorSchema } }
    }
  }
});

// 创建街道查询路由（多租户）
const getTownsRoute = createRoute({
  method: 'get',
  path: '/towns',
  middleware: [ authMiddleware ],
  request: {
    query: getTownsSchema
  },
  responses: {
    200: {
      description: '获取街道列表成功',
      content: {
        'application/json': { schema: townsResponseSchema }
      }
    },
    400: {
      description: '参数错误',
      content: { 'application/json': { schema: errorSchema } }
    },
    500: {
      description: '获取街道列表失败',
      content: { 'application/json': { schema: errorSchema } }
    }
  }
});

const app = new OpenAPIHono<AuthContext>()
  .openapi(getProvincesRoute, async (c) => {
    try {
      const { page, pageSize } = c.req.valid('query');
      const tenantId = c.get('tenantId')!;
      const areaService = new AreaServiceMt(AppDataSource);

      // 使用高效查询方法获取指定租户的省份数据
      const provinces = await areaService.getAreasByLevelAndParent(tenantId, AreaLevel.PROVINCE);

      // 分页
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedProvinces = provinces.slice(startIndex, endIndex);

      return c.json({
        success: true,
        data: {
          provinces: paginatedProvinces,
          pagination: {
            page,
            pageSize,
            total: provinces.length,
            totalPages: Math.ceil(provinces.length / pageSize)
          }
        },
        message: '获取省份列表成功'
      }, 200);
    } catch (error) {
      console.error('获取省份列表失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取省份列表失败'
      }, 500);
    }
  })
  .openapi(getCitiesRoute, async (c) => {
    try {
      const { provinceId, page, pageSize } = c.req.valid('query');
      const tenantId = c.get('tenantId')!;
      const areaService = new AreaServiceMt(AppDataSource);

      // 使用高效查询方法获取指定租户和省份下的城市数据
      const cities = await areaService.getAreasByLevelAndParent(tenantId, AreaLevel.CITY, provinceId);

      // 分页
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedCities = cities.slice(startIndex, endIndex);

      return c.json({
        success: true,
        data: {
          cities: paginatedCities,
          pagination: {
            page,
            pageSize,
            total: cities.length,
            totalPages: Math.ceil(cities.length / pageSize)
          }
        },
        message: '获取城市列表成功'
      }, 200);
    } catch (error) {
      console.error('获取城市列表失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取城市列表失败'
      }, 500);
    }
  })
  .openapi(getDistrictsRoute, async (c) => {
    try {
      const { cityId, page, pageSize } = c.req.valid('query');
      const tenantId = c.get('tenantId')!;
      const areaService = new AreaServiceMt(AppDataSource);

      // 使用高效查询方法获取指定租户和城市下的区县数据
      const districts = await areaService.getAreasByLevelAndParent(tenantId, AreaLevel.DISTRICT, cityId!);

      // 分页
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedDistricts = districts.slice(startIndex, endIndex);

      return c.json({
        success: true,
        data: {
          districts: paginatedDistricts,
          pagination: {
            page,
            pageSize,
            total: districts.length,
            totalPages: Math.ceil(districts.length / pageSize)
          }
        },
        message: '获取区县列表成功'
      }, 200);
    } catch (error) {
      console.error('获取区县列表失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取区县列表失败'
      }, 500);
    }
  })
  .openapi(getTownsRoute, async (c) => {
    try {
      const { districtId, page, pageSize } = c.req.valid('query');
      const tenantId = c.get('tenantId')!;
      const areaService = new AreaServiceMt(AppDataSource);

      // 使用高效查询方法获取指定租户和区县下的街道数据
      const towns = await areaService.getAreasByLevelAndParent(tenantId, AreaLevel.TOWN, districtId!);

      // 分页
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedTowns = towns.slice(startIndex, endIndex);

      return c.json({
        success: true,
        data: {
          towns: paginatedTowns,
          pagination: {
            page,
            pageSize,
            total: towns.length,
            totalPages: Math.ceil(towns.length / pageSize)
          }
        },
        message: '获取街道列表成功'
      }, 200);
    } catch (error) {
      console.error('获取街道列表失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '获取街道列表失败'
      }, 500);
    }
  });

export const areasRoutesMt = app;
export default app;