using System;
using System.Linq;
using System.Collections.Generic;
using CncModels.Dto;
using CncModels.Dto.CollectAddress;
using CncRepository.Interface;
using CncService.Interface;
using CncService;
using CncModels.Entity;

namespace CncService.Impl
{
    /// <summary>
    /// 采集地址实现
    /// </summary>
    public class CollectAddressService : ICollectAddressService
    {
        private readonly ICollectAddressRepository _collectAddressRepository;
        private readonly IMachineRepository _machineRepository;
        private readonly IBrandRepository _brandRepository;
        private readonly IWorkshopRepository _workshopRepository;
        private readonly ICollectRawRepository _collectRawRepository;
        private readonly ISysConfigRepository _sysConfigRepository;

        public CollectAddressService(ICollectAddressRepository collectAddressRepository,
            IMachineRepository machineRepository,
            IBrandRepository brandRepository,
            IWorkshopRepository workshopRepository,
            ICollectRawRepository collectRawRepository,
            ISysConfigRepository sysConfigRepository)
        {
            _collectAddressRepository = collectAddressRepository;
            _machineRepository = machineRepository;
            _brandRepository = brandRepository;
            _workshopRepository = workshopRepository;
            _collectRawRepository = collectRawRepository;
            _sysConfigRepository = sysConfigRepository;
        }

        /// <summary>从sys_config读取在线超时阈值（秒）</summary>
        private int GetOnlineTimeout()
        {
            var cfg = _sysConfigRepository.GetByKey("online_timeout");
            if (cfg != null && int.TryParse(cfg.ConfigValue, out var val) && val > 0) return val;
            return 300;
        }

        public PagedResult<CollectAddressListItem> GetList(CollectAddressQuery query)
        {
            return _collectAddressRepository.GetList(query);
        }

        public CollectAddressDetailResponse GetById(int id)
        {
            var detail = _collectAddressRepository.GetById(id);
            if (detail == null) throw new BusinessException(CncModels.Constants.ErrorCode.NotFound, "采集地址不存在");
            string brandName = null;
            var brand = _brandRepository.GetById(detail.BrandId);
            if (brand != null) brandName = brand.BrandName;
            // 直接映射到输出 DTO
            return new CollectAddressDetailResponse
            {
                Id = detail.Id,
                Name = detail.Name,
                Url = detail.Url,
                BrandId = detail.BrandId,
                BrandName = brandName,
                CollectInterval = detail.CollectInterval,
                IsEnabled = detail.IsEnabled == 1
            };
        }

        public int Create(CreateCollectAddressRequest request)
        {
            if (request == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数错误");
            if (_brandRepository.GetById(request.BrandId) == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.NotFound, "品牌不存在");
            var entity = new CollectAddress
            {
                Name = request.Name,
                Url = request.Url,
                BrandId = request.BrandId,
                CollectInterval = request.CollectInterval,
                IsEnabled = 1,
                CreatedAt = DateTime.Now,
                UpdatedAt = DateTime.Now
            };
            var id = _collectAddressRepository.Create(entity);

            // 绑定机床
            if (request.MachineIds != null)
            {
                foreach (var mid in request.MachineIds)
                {
                    _machineRepository.SetCollectAddress(mid, id);
                }
            }
            return id;
        }

        public bool Update(int id, UpdateCollectAddressRequest request)
        {
            var address = _collectAddressRepository.GetById(id);
            if (address == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.NotFound, "采集地址不存在");
            if (request == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数错误");

            address.Name = request.Name ?? address.Name;
            address.Url = request.Url ?? address.Url;
            address.BrandId = (request.BrandId != 0) ? request.BrandId : address.BrandId;
            address.CollectInterval = (request.CollectInterval != 0) ? request.CollectInterval : address.CollectInterval;
            address.UpdatedAt = DateTime.Now;
            _collectAddressRepository.Update(address);

            // 全量替换机床关联
            if (request.MachineIds != null)
            {
                // 先清除该地址下所有机床的关联
                var currentMachines = _machineRepository.GetEnabledByAddressId(id);
                foreach (var m in currentMachines)
                {
                    _machineRepository.SetCollectAddress(m.Id, null);
                }
                // 再绑定新选中的机床
                foreach (var mid in request.MachineIds)
                {
                    _machineRepository.SetCollectAddress(mid, id);
                }
            }
            return true;
        }

        public bool Delete(int id)
        {
            // 检查关联机床数量
            var count = _collectAddressRepository.GetMachineCount(id);
            if (count > 0) throw new BusinessException(CncModels.Constants.ErrorCode.DataReferenced, $"该地址下有 {count} 台机床，请先解除关联");
            return _collectAddressRepository.Delete(id);
        }

        public int BatchDelete(List<int> ids)
        {
            if (ids == null || ids.Count == 0) throw new BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请选择要删除的采集地址");
            // 检查每个地址下是否有关联机床
            foreach (var id in ids)
            {
                var count = _collectAddressRepository.GetMachineCount(id);
                if (count > 0) throw new BusinessException(CncModels.Constants.ErrorCode.DataReferenced, $"地址(ID={id})下有 {count} 台机床，请先解除关联");
            }
            return _collectAddressRepository.BatchDelete(ids);
        }

        public bool ToggleEnabled(int id)
        {
            return _collectAddressRepository.ToggleEnabled(id);
        }

        /// <inheritdoc/>
        public List<CollectAddressMachineItem> GetMachines(int collectAddressId)
        {
            var machines = _machineRepository.GetEnabledByAddressId(collectAddressId);
            var result = new List<CollectAddressMachineItem>();
            foreach (var m in machines)
            {
                string workshopName = null;
                if (m.WorkshopId > 0)
                {
                    var workshop = _workshopRepository.GetById(m.WorkshopId);
                    if (workshop != null) workshopName = workshop.Name;
                }
                result.Add(new CollectAddressMachineItem
                {
                    MachineId = m.Id,
                    MachineName = m.Name ?? m.DeviceCode,
                    DeviceCode = m.DeviceCode,
                    WorkshopName = workshopName,
                    IsOnline = m.IsEnabled == 1 && m.LastPingTime.HasValue && (DateTime.Now - m.LastPingTime.Value).TotalSeconds <= GetOnlineTimeout(),
                    ProgramName = m.LastProgramName
                });
            }
            return result;
        }

        /// <inheritdoc/>
        public List<CollectAddressRecordItem> GetCollectRecords(int collectAddressId)
        {
            var paged = _collectRawRepository.GetByAddressId(collectAddressId, 1, 20);
            var result = new List<CollectAddressRecordItem>();
            foreach (var r in paged.Items)
            {
                result.Add(new CollectAddressRecordItem
                {
                    RequestTime = r.RequestTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Duration = r.ResponseDuration ?? 0,
                    IsSuccess = r.IsSuccess == 1,
                    MachineCount = 0, // 采集服务运行时从JSON解析得到
                    MachineName = ""
                });
            }
            return result;
        }

        /// <inheritdoc/>
        public CollectAddressRawJsonResponse GetRawJson(int collectAddressId, string recordId = null)
        {
            // 优先按 recordId（请求时间）查找，否则取最新一条
            CollectRaw raw = null;
            if (!string.IsNullOrEmpty(recordId))
            {
                var paged = _collectRawRepository.GetByAddressId(collectAddressId, 1, 100);
                DateTime dt;
                if (DateTime.TryParse(recordId, out dt))
                {
                    raw = paged.Items.FirstOrDefault(r => r.RequestTime.ToString("yyyy-MM-dd HH:mm:ss") == recordId);
                }
            }
            if (raw == null)
            {
                raw = _collectRawRepository.GetLatestByAddressId(collectAddressId);
            }
            return new CollectAddressRawJsonResponse
            {
                RawJson = raw?.RawJson ?? "[]"
            };
        }
    }
}
