package routes

import (
	"github.com/gofiber/fiber/v2"

	"github.com/break/junhong_cmp_fiber/internal/gateway"
	"github.com/break/junhong_cmp_fiber/internal/handler/admin"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/pkg/openapi"
)

func registerDeviceRoutes(router fiber.Router, handler *admin.DeviceHandler, importHandler *admin.DeviceImportHandler, doc *openapi.Generator, basePath string) {
	devices := router.Group("/devices")
	groupPath := basePath + "/devices"

	Register(devices, doc, groupPath, "GET", "", handler.List, RouteSpec{
		Summary: "设备列表",
		Tags:    []string{"设备管理"},
		Input:   new(dto.ListDeviceRequest),
		Output:  new(dto.ListDeviceResponse),
		Auth:    true,
	})

	Register(devices, doc, groupPath, "POST", "/batch-update-realname-policy", handler.BatchUpdateRealnamePolicy, RouteSpec{
		Summary:     "批量更新设备实名认证策略",
		Description: "单次最多500条；先校验整批资产及数据权限，再在单事务内全成全败更新。设备下卡存在策略冲突时，C端以设备策略为准。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.BatchUpdateAssetRealnamePolicyRequest),
		Output:      new(dto.BatchUpdateAssetRealnamePolicyResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "DELETE", "/:virtual_no", handler.Delete, RouteSpec{
		Summary:     "删除设备",
		Description: "仅平台用户可操作。删除设备时自动解绑所有卡（卡不会被删除）。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.DeleteDeviceRequest),
		Output:      nil,
		Auth:        true,
	})

	Register(devices, doc, groupPath, "GET", "/:virtual_no/cards", handler.ListCards, RouteSpec{
		Summary: "获取设备绑定的卡列表",
		Tags:    []string{"设备管理"},
		Input:   new(dto.ListDeviceCardsRequest),
		Output:  new(dto.ListDeviceCardsResponse),
		Auth:    true,
	})

	Register(devices, doc, groupPath, "POST", "/:virtual_no/cards", handler.BindCard, RouteSpec{
		Summary:     "绑定卡到设备",
		Description: "仅平台用户可操作。用于导入后调整卡绑定关系（补卡、换卡）。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.BindCardToDeviceRequest),
		Output:      new(dto.BindCardToDeviceResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "DELETE", "/:virtual_no/cards/:iccid", handler.UnbindCard, RouteSpec{
		Summary:     "解绑设备上的卡",
		Description: "仅平台用户可操作。解绑不改变卡的 shop_id。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.UnbindCardFromDeviceRequest),
		Output:      new(dto.UnbindCardFromDeviceResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/allocate", handler.Allocate, RouteSpec{
		Summary:     "批量分配设备",
		Description: "分配设备给直属下级店铺。分配时自动同步绑定的所有卡的 shop_id。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.AllocateDevicesRequest),
		Output:      new(dto.AllocateDevicesResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/recall", handler.Recall, RouteSpec{
		Summary:     "批量回收设备",
		Description: "从直属下级店铺回收设备。回收时自动同步绑定的所有卡的 shop_id。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.RecallDevicesRequest),
		Output:      new(dto.RecallDevicesResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/import", importHandler.Import, RouteSpec{
		Summary: "批量导入设备",
		Description: `仅平台用户可操作。文件格式已从 CSV 升级为 Excel (.xlsx)。

### 完整导入流程

1. **获取上传 URL**: 调用 ` + "`POST /api/admin/storage/upload-url`" + `
2. **上传 Excel 文件**: 使用预签名 URL 上传文件到对象存储
3. **调用本接口**: 使用返回的 ` + "`file_key`" + ` 提交导入任务

### Excel 文件格式

- 文件格式：仅支持 .xlsx (Excel 2007+)
- 必须包含列（首行为表头）:
   - ` + "`virtual_no`" + `: 设备虚拟号（**必填**，全局唯一；**为空的行记为失败，不再静默跳过**）
  - ` + "`sn`" + `: 设备 SN
  - ` + "`device_name`" + `: 设备名称
  - ` + "`device_model`" + `: 设备型号
  - ` + "`device_type`" + `: 设备类型
  - ` + "`imei`" + `: 设备 IMEI
  - ` + "`manufacturer`" + `: 制造商
  - ` + "`max_sim_slots`" + `: 最大插槽数（默认4，范围1-4）
  - ` + "`iccid_1`" + ` ~ ` + "`iccid_4`" + `: 固定槽位的卡 ICCID（` + "`iccid_1`" + `=槽1，` + "`iccid_2`" + `=槽2，` + "`iccid_3`" + `=槽3，` + "`iccid_4`" + `=槽4；卡必须已存在且未绑定）
- 槽位规则：中间留空不会触发前移补位；如果 ` + "`max_sim_slots=2`" + `，则 ` + "`iccid_3`" + `、` + "`iccid_4`" + ` 必须留空，否则该行失败
- 固定列顺序：` + "`virtual_no`" + `、` + "`sn`" + `、` + "`device_name`" + `、` + "`device_model`" + `、` + "`device_type`" + `、` + "`imei`" + `、` + "`manufacturer`" + `、` + "`max_sim_slots`" + `、` + "`iccid_1`" + `、` + "`iccid_2`" + `、` + "`iccid_3`" + `、` + "`iccid_4`" + `
- 列格式：设置为文本格式(避免长数字被转为科学记数法)`,
		Tags:   []string{"设备管理"},
		Input:  new(dto.ImportDeviceRequest),
		Output: new(dto.ImportDeviceResponse),
		Auth:   true,
	})

	Register(devices, doc, groupPath, "GET", "/import/tasks", importHandler.List, RouteSpec{
		Summary:     "导入任务列表",
		Description: "仅平台用户可操作。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.ListDeviceImportTaskRequest),
		Output:      new(dto.ListDeviceImportTaskResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/import/allocations", importHandler.CreateAllocation, RouteSpec{
		Summary:     "创建CSV设备批量分配任务",
		Description: "复用设备导入任务。CSV只能包含一列设备标识，每行支持VirtualNo、IMEI或SN；整批选择分配目标代理或设置目标套餐系列。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.CreateDeviceBatchAllocationRequest),
		Output:      new(dto.CreateDeviceBatchAllocationResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "GET", "/import/tasks/:id", importHandler.GetByID, RouteSpec{
		Summary:     "导入任务详情",
		Description: "仅平台用户可操作。包含跳过和失败记录的详细信息。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.GetDeviceImportTaskRequest),
		Output:      new(dto.DeviceImportTaskDetailResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "PATCH", "/series-binding", handler.BatchSetSeriesBinding, RouteSpec{
		Summary:     "批量设置设备的套餐系列绑定",
		Description: "批量设置或清除设备与套餐系列分配的关联关系。series_id 为目标套餐系列ID，0表示清除关联。支持 selection_type=list/range/filter：list 传 device_ids（兼容旧请求，不传 selection_type 时默认按 device_ids 处理），range 传 virtual_no_start/virtual_no_end，filter 按筛选条件选择完整结果，不受列表分页限制。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.BatchSetDeviceSeriesBindngRequest),
		Output:      new(dto.BatchSetDeviceSeriesBindngResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "GET", "/by-identifier/:identifier/gateway-slots", handler.GetGatewaySlots, RouteSpec{
		Summary:     "查询卡槽信息",
		Description: "通过虚拟号/IMEI/SN 查询设备卡槽信息。设备必须已配置 IMEI。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.GetDeviceByIdentifierRequest),
		Output:      new(gateway.SlotInfoResp),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "PUT", "/by-identifier/:identifier/wifi", handler.SetWiFi, RouteSpec{
		Summary:     "设置 WiFi",
		Description: "通过虚拟号/IMEI/SN 设置设备 WiFi。设备必须已配置 IMEI。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.SetWiFiRequest),
		Output:      new(dto.EmptyResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/by-identifier/:identifier/switch-card", handler.SwitchCard, RouteSpec{
		Summary:     "切卡",
		Description: "通过虚拟号/IMEI/SN 切换设备当前使用的卡。设备必须已配置 IMEI。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.SwitchCardRequest),
		Output:      new(dto.EmptyResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/by-identifier/:identifier/switch-mode", handler.SetSwitchMode, RouteSpec{
		Summary:     "设置切卡模式",
		Description: "通过虚拟号/IMEI/SN 设置设备切卡模式（0:自动切卡, 1:手动切卡）。设备必须已配置 IMEI，且必须指定一张系统内状态正常并已实名的目标卡资产ID。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.SetSwitchModeRequest),
		Output:      new(dto.EmptyResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/by-identifier/:identifier/reboot", handler.RebootDevice, RouteSpec{
		Summary:     "重启设备",
		Description: "通过虚拟号/IMEI/SN 重启设备。设备必须已配置 IMEI。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.GetDeviceByIdentifierRequest),
		Output:      new(dto.EmptyResponse),
		Auth:        true,
	})

	Register(devices, doc, groupPath, "POST", "/by-identifier/:identifier/reset", handler.ResetDevice, RouteSpec{
		Summary:     "恢复出厂",
		Description: "通过虚拟号/IMEI/SN 恢复设备出厂设置。设备必须已配置 IMEI。",
		Tags:        []string{"设备管理"},
		Input:       new(dto.GetDeviceByIdentifierRequest),
		Output:      new(dto.EmptyResponse),
		Auth:        true,
	})
}
