import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { z, ZodError } from 'zod';
import { GoodsSchema } from '../schemas/goods.schema.mt';
import { ErrorSchema } from '@d8d/shared-utils';
import { AppDataSource } from '@d8d/shared-utils';
import { GoodsMt } from '../entities/goods.entity.mt';
import { AuthContext } from '@d8d/shared-types';
import { authMiddleware } from '@d8d/auth-module-mt';
import { parseWithAwait } from '@d8d/shared-utils';

// 定义批量创建子商品Schema
const BatchCreateChildrenSchema = z.object({
  parentGoodsId: z.coerce.number<Number>().int().positive('父商品ID必须是正整数'),
  specs: z.array(z.object({
    name: z.string().min(1, '规格名称不能为空').max(255, '规格名称不能超过255个字符'),
    price: z.coerce.number<Number>().nonnegative('价格不能为负数'),
    costPrice: z.coerce.number<Number>().nonnegative('成本价不能为负数'),
    stock: z.coerce.number<Number>().int().nonnegative('库存不能为负数'),
    sort: z.coerce.number<Number>().int().default(0)
  })).min(1, '至少需要一个规格')
});

// 1. 获取子商品列表路由
const getChildrenRoute = createRoute({
  method: 'get',
  path: '/{id}/children',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.coerce.number<Number>().int().positive('商品ID必须是正整数')
    }),
    query: z.object({
      page: z.coerce.number<Number>().int().positive('页码必须是正整数').default(1),
      pageSize: z.coerce.number<Number>().int().positive('每页数量必须是正整数').default(10),
      keyword: z.string().optional(),
      sortBy: z.string().optional().default('sort'),
      sortOrder: z.enum(['ASC', 'DESC']).optional().default('ASC')
    })
  },
  responses: {
    200: {
      description: '成功获取子商品列表',
      content: {
        'application/json': {
          schema: z.object({
            data: z.array(GoodsSchema),
            total: z.coerce.number<Number>().int().nonnegative(),
            page: z.coerce.number<Number>().int().positive(),
            pageSize: z.coerce.number<Number>().int().positive(),
            totalPages: z.coerce.number<Number>().int().nonnegative()
          })
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '父商品不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 2. 设为父商品路由
const setAsParentRoute = createRoute({
  method: 'post',
  path: '/{id}/set-as-parent',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.coerce.number<Number>().int().positive('商品ID必须是正整数')
    })
  },
  responses: {
    200: {
      description: '成功设为父商品',
      content: {
        'application/json': {
          schema: GoodsSchema
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '商品不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 3. 解除父子关系路由
const removeParentRoute = createRoute({
  method: 'delete',
  path: '/{id}/parent',
  middleware: [authMiddleware],
  request: {
    params: z.object({
      id: z.coerce.number<Number>().int().positive('商品ID必须是正整数')
    })
  },
  responses: {
    200: {
      description: '成功解除父子关系',
      content: {
        'application/json': {
          schema: GoodsSchema
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    404: {
      description: '商品不存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

// 4. 批量创建子商品路由
const batchCreateChildrenRoute = createRoute({
  method: 'post',
  path: '/batchCreateChildren',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': {
          schema: BatchCreateChildrenSchema
        }
      }
    }
  },
  responses: {
    200: {
      description: '成功批量创建子商品',
      content: {
        'application/json': {
          schema: z.object({
            success: z.boolean(),
            count: z.number().int().nonnegative(),
            children: z.array(GoodsSchema)
          })
        }
      }
    },
    400: {
      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. 实现获取子商品列表
.openapi(getChildrenRoute, async (c) => {
  try {
    const { id: parentId } = c.req.valid('param');
    const query = c.req.valid('query');
    const { page, pageSize, keyword, sortBy, sortOrder } = query;

    // 获取当前用户和租户
    const user = c.get('user');
    const tenantId = c.get('tenantId');

    console.debug('获取子商品列表请求参数:', {
      parentId,
      query,
      tenantId,
      user: user ? { id: user.id, username: user.username, tenantId: user.tenantId } : null
    });

    if (!tenantId) {
      console.debug('无法获取租户信息，用户对象:', user);
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '无法获取租户信息'
      });
      return c.json(error, 400);
    }

    // 验证父商品是否存在且属于当前租户
    const parentGoods = await AppDataSource.getRepository(GoodsMt).findOne({
      where: { id: parentId, tenantId } as any,
      select: ['id', 'name']
    });

    if (!parentGoods) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 404,
        message: '父商品不存在'
      });
      return c.json(error, 404);
    }

    // 创建查询构建器
    const queryBuilder = AppDataSource.getRepository(GoodsMt)
      .createQueryBuilder('goods')
      .where('goods.tenant_id = :tenantId', { tenantId })
      .andWhere('goods.spu_id = :spuId', { spuId: parentId });

    // 搜索关键词过滤
    if (keyword) {
      queryBuilder.andWhere(
        '(goods.name LIKE :keyword OR goods.instructions LIKE :keyword)',
        { keyword: `%${keyword}%` }
      );
    }

    // 排序
    queryBuilder.orderBy(`goods.${sortBy}`, sortOrder);

    // 加载关联关系
    queryBuilder
      .leftJoinAndSelect('goods.category1', 'category1')
      .leftJoinAndSelect('goods.category2', 'category2')
      .leftJoinAndSelect('goods.category3', 'category3')
      .leftJoinAndSelect('goods.supplier', 'supplier')
      .leftJoinAndSelect('goods.merchant', 'merchant')
      .leftJoinAndSelect('goods.imageFile', 'imageFile')
      .leftJoinAndSelect('imageFile.uploadUser', 'imageFile_uploadUser');

    // 分页
    const skip = (page - 1) * pageSize;
    queryBuilder.skip(skip).take(pageSize);

    // 获取子商品列表
    const children = await queryBuilder.getMany();
    const total = await queryBuilder.getCount();

    // 验证数据格式
    const validatedChildren = await parseWithAwait(z.array(GoodsSchema), children);

    return c.json({
      data: validatedChildren,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize)
    }, 200);
  } catch (error) {
    console.error('获取子商品列表失败:', error);
    const errorResponse = await parseWithAwait(ErrorSchema, {
      code: 500,
      message: error instanceof Error ? error.message : '获取子商品列表失败'
    });
    return c.json(errorResponse, 500);
  }
})

// 2. 实现设为父商品
.openapi(setAsParentRoute, async (c) => {
  try {
    const { id } = c.req.valid('param');

    // 获取当前用户和租户
    const user = c.get('user');
    const tenantId = c.get('tenantId');

    if (!tenantId) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '无法获取租户信息'
      });
      return c.json(error, 400);
    }

    // 获取商品
    const goods = await AppDataSource.getRepository(GoodsMt).findOne({
      where: { id, tenantId } as any
    });

    if (!goods) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 404,
        message: '商品不存在'
      });
      return c.json(error, 404);
    }

    // 验证：不能是子商品
    if (goods.spuId > 0) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '子商品不能设为父商品'
      });
      return c.json(error, 400);
    }

    // 更新商品为父商品（spuId已经是0，不需要修改）
    // 主要是确保spuName为null
    goods.spuName = null;

    // 保存更新
    await AppDataSource.getRepository(GoodsMt).save(goods);

    // 验证返回数据
    const validatedGoods = await parseWithAwait(GoodsSchema, goods);

    return c.json(validatedGoods, 200);
  } catch (error) {
    console.error('设为父商品失败:', error);
    const errorResponse = await parseWithAwait(ErrorSchema, {
      code: 500,
      message: error instanceof Error ? error.message : '设为父商品失败'
    });
    return c.json(errorResponse, 500);
  }
})

// 3. 实现解除父子关系
.openapi(removeParentRoute, async (c) => {
  try {
    const { id } = c.req.valid('param');

    // 获取当前用户和租户
    const user = c.get('user');
    const tenantId = c.get('tenantId');

    if (!tenantId) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '无法获取租户信息'
      });
      return c.json(error, 400);
    }

    // 获取商品
    const goods = await AppDataSource.getRepository(GoodsMt).findOne({
      where: { id, tenantId } as any
    });

    if (!goods) {
      const error = await parseWithAwait(ErrorSchema, {
        code: 404,
        message: '商品不存在'
      });
      return c.json(error, 404);
    }

    // 验证：必须是子商品
    if (goods.spuId === 0) {
      return c.json({
        code: 400,
        message: '该商品不是子商品'
      }, 400);
    }

    // 解除父子关系
    const originalSpuId = goods.spuId;
    const originalSpuName = goods.spuName;

    goods.spuId = 0;
    goods.spuName = null;

    // 保存更新
    await AppDataSource.getRepository(GoodsMt).save(goods);

    console.debug('解除父子关系成功:', {
      goodsId: id,
      originalSpuId,
      originalSpuName,
      newSpuId: goods.spuId,
      newSpuName: goods.spuName
    });

    // 验证返回数据
    const validatedGoods = await parseWithAwait(GoodsSchema, goods);

    return c.json(validatedGoods, 200);
  } catch (error) {
    console.error('解除父子关系失败:', error);
    return c.json({
      code: 500,
      message: error instanceof Error ? error.message : '解除父子关系失败'
    }, 500);
  }
})

// 4. 实现批量创建子商品
.openapi(batchCreateChildrenRoute, async (c) => {
  const queryRunner = AppDataSource.createQueryRunner();
  await queryRunner.connect();
  await queryRunner.startTransaction();

  try {
    const { parentGoodsId, specs } = c.req.valid('json');

    // 获取当前用户和租户
    const user = c.get('user');
    const tenantId = c.get('tenantId');
    const userId = user?.id;

    if (!tenantId || !userId) {
      await queryRunner.rollbackTransaction();
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '无法获取用户信息'
      });
      return c.json(error, 400);
    }

    // 获取父商品
    const parentGoods = await queryRunner.manager.findOne(GoodsMt, {
      where: { id: parentGoodsId, tenantId } as any,
      select: ['id', 'name', 'categoryId1', 'categoryId2', 'categoryId3', 'goodsType', 'supplierId', 'merchantId', 'spuId', 'imageFileId']
    });

    if (!parentGoods) {
      await queryRunner.rollbackTransaction();
      const error = await parseWithAwait(ErrorSchema, {
        code: 404,
        message: '父商品不存在'
      });
      return c.json(error, 404);
    }

    // 验证父商品必须是父商品（spuId=0）
    if (parentGoods.spuId !== 0) {
      await queryRunner.rollbackTransaction();
      const error = await parseWithAwait(ErrorSchema, {
        code: 400,
        message: '只能为父商品创建子商品'
      });
      return c.json(error, 400);
    }

    // 批量创建子商品
    const createdChildren = [];
    for (const spec of specs) {
      const childGoods = new GoodsMt();

      // 继承父商品信息
      childGoods.tenantId = tenantId;
      childGoods.name = spec.name;
      childGoods.price = spec.price;
      childGoods.costPrice = spec.costPrice;
      childGoods.stock = spec.stock;
      childGoods.sort = spec.sort;
      childGoods.state = 1; // 默认可用状态

      // 父子关系
      childGoods.spuId = parentGoodsId;
      childGoods.spuName = parentGoods.name;

      // 继承分类和其他信息
      childGoods.categoryId1 = parentGoods.categoryId1;
      childGoods.categoryId2 = parentGoods.categoryId2;
      childGoods.categoryId3 = parentGoods.categoryId3;
      childGoods.goodsType = parentGoods.goodsType;
      childGoods.supplierId = parentGoods.supplierId;
      childGoods.merchantId = parentGoods.merchantId;
      childGoods.imageFileId = parentGoods.imageFileId;

      // 用户跟踪
      childGoods.createdBy = userId;
      childGoods.updatedBy = userId;

      // 保存子商品
      const savedChild = await queryRunner.manager.save(childGoods);
      createdChildren.push(savedChild);
    }

    // 提交事务
    await queryRunner.commitTransaction();

    console.debug('批量创建子商品成功:', {
      parentGoodsId,
      count: createdChildren.length,
      children: createdChildren.map(c => ({ id: c.id, name: c.name }))
    });

    // 验证返回数据
    const validatedChildren = await parseWithAwait(z.array(GoodsSchema), createdChildren);

    return c.json({
      success: true,
      count: createdChildren.length,
      children: validatedChildren
    }, 200);
  } catch (error) {
    // 回滚事务
    await queryRunner.rollbackTransaction();
    console.error('批量创建子商品失败:', error);

    // 处理Zod验证错误
    if (error instanceof ZodError) {
      const errorResponse = {
        code: 400,
        message: error.message
      };
      return c.json(errorResponse, 400);
    }

    // 其他错误返回500
    const errorResponse = await parseWithAwait(ErrorSchema, {
      code: 500,
      message: error instanceof Error ? error.message : '批量创建子商品失败'
    });
    return c.json(errorResponse, 500);
  } finally {
    await queryRunner.release();
  }
})

export const adminGoodsParentChildRoutesMt = app;