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

namespace CncRepository.Impl
{
    /// <summary>
    /// 采集地址实现
    /// </summary>
    public class CollectAddressRepository : BusinessRepository, ICollectAddressRepository
    {
        public CollectAddressRepository(string connectionString) : base(connectionString) { }

        /// <summary>采集地址SELECT列映射模板</summary>
        private const string SelectColumns = @"id as Id, name as Name, url as Url, brand_id as BrandId, collect_interval as CollectInterval, is_enabled as IsEnabled, last_collect_time as LastCollectTime, last_collect_status as LastCollectStatus, fail_count as FailCount, created_at as CreatedAt, updated_at as UpdatedAt";

        public CollectAddress GetById(int id)
        {
            using (var conn = CreateConnection())
            {
                var sql = $"SELECT {SelectColumns} FROM cnc_collect_address WHERE id = @Id";
                return conn.QuerySingleOrDefault<CollectAddress>(sql, new { Id = id });
            }
        }

        public PagedResult<CollectAddressListItem> GetList(CollectAddressQuery query)
        {
            using (var conn = CreateConnection())
            {
                var where = " WHERE 1=1";
                var parameters = new DynamicParameters();
                if (!string.IsNullOrWhiteSpace(query.Keyword))
                {
                    where += " AND (ca.name LIKE @Keyword OR ca.url LIKE @Keyword)";
                    parameters.Add("Keyword", $"%{query.Keyword}%");
                }
                if (query.BrandId.HasValue)
                {
                    where += " AND ca.brand_id = @BrandId";
                    parameters.Add("BrandId", query.BrandId.Value);
                }
                if (query.IsEnabled.HasValue)
                {
                    where += " AND ca.is_enabled = @IsEnabled";
                    parameters.Add("IsEnabled", query.IsEnabled.Value);
                }

                var limit = query.PageSize;
                var offset = query.Offset;
                var sql = @"SELECT ca.id as Id, ca.name as Name, ca.url as Url, ca.brand_id as BrandId, b.brand_name as BrandName, ca.collect_interval as CollectInterval, ca.is_enabled as IsEnabled, ca.last_collect_time as LastCollectTime, 
                              (SELECT COUNT(*) FROM cnc_machine m WHERE m.collect_address_id = ca.id) as MachineCount 
                              FROM cnc_collect_address ca LEFT JOIN cnc_brand b ON ca.brand_id = b.id" + where + @" ORDER BY ca.id DESC LIMIT @Limit OFFSET @Offset";
                parameters.Add("Limit", limit);
                parameters.Add("Offset", offset);

                var totalSql = @"SELECT COUNT(*) FROM cnc_collect_address ca LEFT JOIN cnc_brand b ON ca.brand_id = b.id" + where;
                var total = conn.ExecuteScalar<int>(totalSql, parameters);
                var items = conn.Query<CollectAddressListItem>(sql, parameters).ToList();

                return new PagedResult<CollectAddressListItem>
                {
                    Items = items,
                    Total = total,
                    Page = query.Page,
                    PageSize = limit
                };
            }
        }

        public int Create(CollectAddress entity)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"INSERT INTO cnc_collect_address (name, url, brand_id, collect_interval, is_enabled, created_at, updated_at) 
                            VALUES (@Name, @Url, @BrandId, @CollectInterval, @IsEnabled, @CreatedAt, @UpdatedAt); 
                          SELECT LAST_INSERT_ID();";
                return conn.QuerySingle<int>(sql, entity);
            }
        }

        public bool Update(CollectAddress entity)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"UPDATE cnc_collect_address SET name = @Name, url = @Url, brand_id = @BrandId, collect_interval = @CollectInterval, is_enabled = @IsEnabled, updated_at = @UpdatedAt WHERE id = @Id";
                return conn.Execute(sql, entity) > 0;
            }
        }

        public bool Delete(int id)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"DELETE FROM cnc_collect_address WHERE id = @Id";
                return conn.Execute(sql, new { Id = id }) > 0;
            }
        }

        public int BatchDelete(List<int> ids)
        {
            if (ids == null || ids.Count == 0) return 0;
            using (var conn = CreateConnection())
            {
                var sql = @"DELETE FROM cnc_collect_address WHERE id IN @Ids";
                return conn.Execute(sql, new { Ids = ids });
            }
        }

        public bool ToggleEnabled(int id)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"UPDATE cnc_collect_address SET is_enabled = CASE WHEN is_enabled = 1 THEN 0 ELSE 1 END, updated_at = NOW() WHERE id = @Id";
                return conn.Execute(sql, new { Id = id }) > 0;
            }
        }

        public List<CollectAddress> GetEnabledList()
        {
            using (var conn = CreateConnection())
            {
                var sql = $"SELECT {SelectColumns} FROM cnc_collect_address WHERE is_enabled = 1";
                return conn.Query<CollectAddress>(sql).ToList();
            }
        }

        public int GetMachineCount(int collectAddressId)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"SELECT COUNT(*) FROM cnc_machine WHERE collect_address_id = @CollectAddressId";
                return conn.ExecuteScalar<int>(sql, new { CollectAddressId = collectAddressId });
            }
        }
    }
}
