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

namespace CncRepository.Impl
{
    /// <summary>
    /// 工人实现
    /// </summary>
    public class WorkerRepository : BusinessRepository, IWorkerRepository
    {
        public WorkerRepository(string connectionString) : base(connectionString) { }

        /// <summary>工人SELECT列映射模板</summary>
        private const string SelectColumns = @"id as Id, name as Name, code as Code, is_enabled as IsEnabled, created_at as CreatedAt, updated_at as UpdatedAt";

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

        public PagedResult<WorkerListItem> GetList(WorkerQuery query)
        {
            using (var conn = CreateConnection())
            {
                var where = " WHERE 1=1";
                var p = new DynamicParameters();
                if (!string.IsNullOrWhiteSpace(query.Keyword))
                {
                    where += " AND (w.name LIKE @Keyword OR w.code LIKE @Keyword)";
                    p.Add("Keyword", $"%{query.Keyword}%");
                }
                if (query.IsEnabled.HasValue)
                {
                    where += " AND w.is_enabled = @IsEnabled";
                    p.Add("IsEnabled", query.IsEnabled.Value);
                }
                var limit = query.PageSize;
                var offset = query.Offset;
                var sql = @"SELECT w.id as Id, w.code as Code, w.name as Name, w.is_enabled as IsEnabled, 
                              (SELECT COUNT(*) FROM cnc_worker_machine wm WHERE wm.worker_id = w.id) as MachineCount, 
                              (SELECT GROUP_CONCAT(m.name SEPARATOR ', ') FROM cnc_worker_machine wm JOIN cnc_machine m ON wm.machine_id = m.id WHERE wm.worker_id = w.id) as MachineNames 
                              FROM cnc_worker w" + where + @" ORDER BY w.id DESC LIMIT @Limit OFFSET @Offset";
                p.Add("Limit", limit);
                p.Add("Offset", offset);
                var totalSql = @"SELECT COUNT(*) FROM cnc_worker w" + where;
                var total = conn.ExecuteScalar<int>(totalSql, p);
                var items = conn.Query<WorkerListItem>(sql, p).ToList();
                return new PagedResult<WorkerListItem>
                {
                    Items = items,
                    Total = total,
                    Page = query.Page,
                    PageSize = limit
                };
            }
        }

        public int Create(Worker entity)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"INSERT INTO cnc_worker (name, code, is_enabled, created_at, updated_at) VALUES (@Name, @Code, @IsEnabled, @CreatedAt, @UpdatedAt); SELECT LAST_INSERT_ID();";
                return conn.QuerySingle<int>(sql, entity);
            }
        }

        public bool Update(Worker entity)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"UPDATE cnc_worker SET name = @Name, code = @Code, 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_worker 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_worker WHERE id IN @Ids";
                return conn.Execute(sql, new { Ids = ids });
            }
        }

        public bool ToggleEnabled(int id)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"UPDATE cnc_worker 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 Worker GetByCode(string code)
        {
            using (var conn = CreateConnection())
            {
                var sql = $"SELECT {SelectColumns} FROM cnc_worker WHERE code = @Code";
                return conn.QuerySingleOrDefault<Worker>(sql, new { Code = code });
            }
        }

        public List<Worker> GetAll()
        {
            using (var conn = CreateConnection())
            {
                var sql = $"SELECT {SelectColumns} FROM cnc_worker ORDER BY id";
                return conn.Query<Worker>(sql).ToList();
            }
        }
    }
}
