// server/index.js
import express from 'express'
import cors from 'cors'
import grpc from '@grpc/grpc-js'
import protoLoader from '@grpc/proto-loader'
import path from 'path'
import { fileURLToPath } from 'url'
import 'dotenv/config';  

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const app = express()
app.use(express.static(path.join(__dirname, '../dist')));
app.use(cors())
app.use(express.json())

// ========== 加载 Proto ==========
const PROTO_ROOT = path.resolve(__dirname, './proto')              // 指向 server/proto/
const PROTO_ENTRY = path.join(PROTO_ROOT, 'cmvr/api/agv_service.proto')

const packageDefinition = protoLoader.loadSync(
  PROTO_ENTRY,
  {
    includeDirs: [PROTO_ROOT , path.join(PROTO_ROOT, 'cmvr/api')],    // 关键：让加载器从 PROTO_ROOT 查找 import
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true
  }
)

const cmvrProto = grpc.loadPackageDefinition(packageDefinition).cmvr.api

const createGrpcClient = (address) => {
  const grpcClient = new cmvrProto.AgvService(
    address,
    grpc.credentials.createInsecure()
  )
  return grpcClient
}

// 获取机器人当前地图名称
app.post('/api/agv/getCurrentMapName', async (req, res) => {
  const request = {
    header: {
      device_id: req.body.device_id || 'agv_src1100'
    }
  };

  const grpcClient = createGrpcClient(req.body.ip)

  const resp = await new Promise((resolve, reject) => {
    grpcClient.getMapStatus(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    });
  })

  if (resp.code === 200) {
    res.json(resp)
  } else {
    res.status(500).json({ error: 'grpc服务端错误' })
  }
})

// 获取机器人当前地图名称
app.post('/api/agv/getCurrentMap', async (req, res) => {
  const grpcClient = createGrpcClient(req.body.ip)
  const request = {
    header: {
      device_id: req.body.device_id || 'agv_src1100'
    },
    data: {
      map_name: req.body.mapName
    }
  };

  const resp = await new Promise((resolve, reject) => {
    grpcClient.RobotConfigDownloadMap(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    });
  })

  if (resp.code === 200) {
    res.json(resp)
  } else {
    res.status(500).json({ error: 'grpc服务端错误' })
  }
})

app.post('/api/agv/getRobotState', async (req, res) => {
  const request = {
    header: {
      device_id: req.body.device_id || 'agv_src1100'
    }
  };

  const grpcClient = createGrpcClient(req.body.ip)

  const response = await new Promise((resolve, reject) => {
    grpcClient.GetRobotLocation(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    })
  })
  const resp = await new Promise((resolve, reject) => {
    grpcClient.GetBatteryStatus(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    });
  })

  if (response.code === 200 && resp.code ===200) {
    res.json({
      code: 200,
      data: {
        x: response.data.x,
        y: response.data.y,
        angle: response.data.angle,
        confidence: response.data.confidence,
        batteryLevel: resp.data.battery_level,
        batteryTemp: resp.data.battery_temp,
        charging: resp.data.charging,
        voltage: resp.data.voltage
      }
    })
  } else {
    res.status(500).json({ error: 'grpc服务端错误' })
  }
})

app.post('/api/agv/moveRobot', async (req, res) => {
  const grpcClient = createGrpcClient(req.body.ip)
  const request = {
    header: {
      device_id: req.body.device_id || 'agv_src1100'
    },
    data: {
      vx: req.body.vx,
      vy: req.body.vy,
      w: req.body.w,
      duration: req.body.duration
    }
  };

  const resp = await new Promise((resolve, reject) => {
    grpcClient.RobotMotionControl(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    });
  })

  if (resp.code === 200) {
    res.json({
      code: 200,
      data: resp
    })
  } else {
    res.status(500).json({ error: 'grpc服务端错误' })
  }
})

app.post('/api/agv/stopRobot', async (req, res) => {
  const grpcClient = createGrpcClient(req.body.ip)
  const request = {
    header: {
      device_id: req.body.device_id || 'agv_src1100'
    }
  };

  const resp = await new Promise((resolve, reject) => {
    grpcClient.RobotControlStop(request, (err, res) => {
      if (err) {
        resolve({
          code: 500,
          data: `grpc服务端错误`
        });
      } else {
        resolve({
          code: 200,
          data: res.status
        });
      }
    });
  })

  if (resp.code === 200) {
    res.json({
      code: 200,
      data: resp
    })
  } else {
    res.status(500).json({ error: 'grpc服务端错误' })
  }
})

const isProd = process.env.NODE_ENV === 'production';
const PORT = process.env.VITE_SERVICE_PORT || 3000;

// ============ 生产环境：托管 Vite 构建产物 ============
if (isProd) {
  const distPath = resolve(__dirname, '../dist');

  // 托管静态文件
  app.use(express.static(distPath));

  // SPA 回退：所有非 API 请求返回 index.html
  app.get('*', (req, res) => {
    res.sendFile(resolve(distPath, 'index.html'));
  });

  app.post('*', (req, res) => {
    res.sendFile(resolve(distPath, 'index.html'));
  });
}

// ========== 启动 =========

app.listen(PORT, () => {
  console.log(`gRPC 桥接服务已启动: http://localhost:${PORT}`)
})