using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Haoliang.Models.Device;
using Haoliang.Data;
using Haoliang.Data.Repositories;
using Haoliang.Data.Entities;

namespace Haoliang.Data.Repositories
{
    public interface IDeviceRepository : IRepository<CNCDevice>
    {
        Task<IEnumerable<CNCDevice>> GetOnlineDevicesAsync();
        Task<IEnumerable<CNCDevice>> GetAvailableDevicesAsync();
        Task<CNCDevice> GetByDeviceCodeAsync(string deviceCode);
        Task<IEnumerable<CNCDevice>> GetByTemplateIdAsync(int templateId);
        Task<bool> DeviceExistsAsync(string deviceCode);
        Task UpdateDeviceStatusAsync(int deviceId, bool isOnline, bool isAvailable);
        Task<int> CountOnlineDevicesAsync();
        Task<int> CountAvailableDevicesAsync();
    }

    public class DeviceRepository : Repository<CNCDevice>, IDeviceRepository
    {
        private readonly CNCDbContext _context;

        public DeviceRepository(CNCDbContext context) : base(context)
        {
            _context = context;
        }

        public async Task<IEnumerable<CNCDevice>> GetOnlineDevicesAsync()
        {
            return await _context.Devices
                .Where(d => d.IsOnline)
                .OrderBy(d => d.DeviceName)
                .ToListAsync();
        }

        public async Task<IEnumerable<CNCDevice>> GetAvailableDevicesAsync()
        {
            return await _context.Devices
                .Where(d => d.IsAvailable)
                .OrderBy(d => d.DeviceName)
                .ToListAsync();
        }

        public async Task<CNCDevice> GetByDeviceCodeAsync(string deviceCode)
        {
            return await _context.Devices
                .FirstOrDefaultAsync(d => d.DeviceCode == deviceCode);
        }

        public async Task<IEnumerable<CNCDevice>> GetByTemplateIdAsync(int templateId)
        {
            return await _context.Devices
                .Where(d => d.TemplateId == templateId)
                .OrderBy(d => d.DeviceName)
                .ToListAsync();
        }

        public async Task<bool> DeviceExistsAsync(string deviceCode)
        {
            return await _context.Devices
                .AnyAsync(d => d.DeviceCode == deviceCode);
        }

        public async Task UpdateDeviceStatusAsync(int deviceId, bool isOnline, bool isAvailable)
        {
            var device = await GetByIdAsync(deviceId);
            if (device != null)
            {
                device.IsOnline = isOnline;
                device.IsAvailable = isAvailable;
                
                if (isOnline)
                {
                    device.LastCollectionTime = DateTime.Now;
                }

                Update(device);
                await SaveAsync();
            }
        }

        public async Task<int> CountOnlineDevicesAsync()
        {
            return await _context.Devices
                .CountAsync(d => d.IsOnline);
        }

        public async Task<int> CountAvailableDevicesAsync()
        {
            return await _context.Devices
                .CountAsync(d => d.IsAvailable);
        }
    }
}