import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { z } from '@hono/zod-openapi';
import { AppDataSource } from '@/server/data-source';
import { StockDataService } from '@/server/modules/stock/stock-data.service';
import { AuthContext } from '@/server/types/context';
import { authMiddleware } from '@/server/middleware/auth.middleware';
import { ErrorSchema } from '@/server/utils/errorHandler';
import dayjs from 'dayjs';

// 路径参数Schema
const GetStockHistoryParams = z.object({
  code: z.string().openapi({
    param: { name: 'code', in: 'path' },
    example: '001339',
    description: '股票代码'
  })
});

// 股票历史数据项Schema
const StockHistoryItemSchema = z.object({
  d: z.string().openapi({
    description: '日期',
    example: '2007-09-13'
  }),
  o: z.number().openapi({
    description: '开盘价',
    example: 40.99
  }),
  h: z.number().openapi({
    description: '最高价',
    example: 59
  }),
  l: z.number().openapi({
    description: '最低价',
    example: 40.99
  }),
  c: z.number().openapi({
    description: '收盘价',
    example: 53.11
  }),
  v: z.number().openapi({
    description: '成交量',
    example: 78854
  }),
  e: z.number().openapi({
    description: '成交额',
    example: 369834688.13
  }),
  zf: z.number().openapi({
    description: '振幅',
    example: 202.13
  }),
  hs: z.number().openapi({
    description: '换手率',
    example: 78.85
  }),
  zd: z.number().openapi({
    description: '涨跌幅',
    example: 496.07
  }),
  // pc: z.number().openapi({
  //   description: '涨跌额',
  //   example: 44.2
  // }),
  ud: z.string().openapi({
    description: '最后更新时间',
    example: '2025-06-29 02:13:11'
  })
});

// 响应Schema
const GetStockHistoryResponse = z.object({
  data: z.array(StockHistoryItemSchema).openapi({
    description: '股票历史K线数据列表',
    example: [
      {
        d: "2007-09-13",
        o: 40.99,
        h: 59,
        l: 40.99,
        c: 53.11,
        v: 78854,
        e: 369834688.13,
        zf: 202.13,
        hs: 78.85,
        zd: 496.07,
        zde: 44.2,
        ud: "2025-06-29 02:13:11"
      }
    ]
  })
});

// 路由定义
const routeDef = createRoute({
  method: 'get',
  path: '/{code}',
  middleware: [authMiddleware],
  request: {
    params: GetStockHistoryParams
  },
  responses: {
    200: {
      description: '成功获取股票历史数据',
      content: { 'application/json': { schema: GetStockHistoryResponse } }
    },
    400: {
      description: '请求参数错误',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '服务器错误',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 路由实现
const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
  try {
    const { code } = c.req.valid('param');
    const service = new StockDataService(AppDataSource);
    
    const rawData = await service.getStockHistory(code);
    
    // 转换服务输出格式为schema要求的格式
    const formattedData = rawData.map(item => ({
      d: dayjs(item.t).format('YYYY-MM-DD') ,                    // 交易时间 -> 日期
      o: item.o,                    // 开盘价
      h: item.h,                    // 最高价
      l: item.l,                    // 最低价
      c: item.c,                    // 收盘价
      v: item.v,                    // 成交量
      e: item.a,                    // 成交额 -> 成交额
      zf: 0,                        // 振幅 (计算值)
      hs: 0,                        // 换手率 (计算值)
      zd: 0,                        // 涨跌幅 (计算值)
      // pc: 0,                       // 涨跌额 (计算值)
      ud: new Date().toISOString()  // 最后更新时间
    }));
    
    // 计算衍生字段
    const processedData = formattedData.map((item, index, array) => {
      if (index === 0) {
        // 第一条数据无法计算涨跌
        return {
          ...item,
          zd: 0,
          // pc: 0,
          zf: 0
        };
      }
      
      const prevItem = array[index - 1];
      const pc = item.c - prevItem.c;  // 涨跌额
      const zd = prevItem.c !== 0 ? (pc / prevItem.c) * 100 : 0;  // 涨跌幅百分比
      const zf = prevItem.c !== 0 ? ((item.h - item.l) / prevItem.c) * 100 : 0;  // 振幅百分比
      
      return {
        ...item,
        zd: parseFloat(zd.toFixed(2)),
        // pc: parseFloat(pc.toFixed(2)),
        zf: parseFloat(zf.toFixed(2))
      };
    });
    
    // 设置换手率为0（需要从其他数据源获取）
    const finalData = processedData.map(item => ({
      ...item,
      hs: 0
    }));
    
    return c.json({ data: finalData }, 200);
  } catch (error) {
    const { code = 500, message = '获取股票历史数据失败' } = error as Error & { code?: number };
    return c.json({ code, message }, 500);
  }
});

export default app;