using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using FCOMMON;

namespace Project.Web
{
    public partial class MachineBridge
    {
        /// <summary>
        /// 게시판 목록 조회 (bidx로 구분: 5=패치내역, 기타=일반게시판)
        /// </summary>
        public string Board_GetList(int bidx, string searchKey)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;// Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    var sql = @"
                        SELECT idx, bidx, header, cate, title, contents, [file], guid, url, wuid, wdate, project, pidx, gcode, [close], remark,
                               root_idx, depth, sort_order, thread_path, is_comment, reply_count,
                               dbo.getUserName(wuid) AS wuid_name
                        FROM EETGW_Board WITH (nolock)
                        WHERE gcode = @gcode AND bidx = @bidx AND (is_comment IS NULL OR is_comment = 0)
                          AND (ISNULL(title,'') LIKE @search OR ISNULL(contents,'') LIKE @search OR ISNULL(wuid,'') LIKE @search)
                        ORDER BY 
                            CASE WHEN root_idx IS NULL THEN idx ELSE root_idx END DESC,
                            thread_path ASC";

                    if(bidx == 5)   //패치내역은 모두가 다 확인할 수있도록 그룹코드를 제한하지 않는다
                    {
                        sql = @"
                        SELECT idx, bidx, header, cate, title, contents, [file], guid, url, wuid, wdate, project, pidx, gcode, [close], remark,
                               root_idx, depth, sort_order, thread_path, is_comment, reply_count,
                               dbo.getUserName(wuid) AS wuid_name
                        FROM EETGW_Board WITH (nolock)
                        WHERE bidx = @bidx AND (is_comment IS NULL OR is_comment = 0)
                          AND (ISNULL(title,'') LIKE @search OR ISNULL(contents,'') LIKE @search OR ISNULL(wuid,'') LIKE @search)
                        ORDER BY 
                            CASE WHEN root_idx IS NULL THEN idx ELSE root_idx END DESC,
                            thread_path ASC";
                    }

                    var cmd = new SqlCommand(sql, conn);

                    cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode;
                    cmd.Parameters.Add("@bidx", SqlDbType.Int).Value = bidx;
                    cmd.Parameters.Add("@search", SqlDbType.NVarChar).Value = $"%{searchKey}%";

                    var list = new List<object>();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            list.Add(new
                            {
                                idx = reader.GetInt32(0),
                                bidx = reader.GetInt32(1),
                                header = reader.IsDBNull(2) ? "" : (reader.GetBoolean(2) ? "공지" : ""),
                                cate = reader.IsDBNull(3) ? "" : reader.GetString(3),
                                title = reader.IsDBNull(4) ? "" : reader.GetString(4),
                                contents = reader.IsDBNull(5) ? "" : reader.GetString(5),
                                file = reader.IsDBNull(6) ? "" : reader.GetString(6),
                                guid = reader.IsDBNull(7) ? "" : reader.GetString(7),
                                url = reader.IsDBNull(8) ? "" : reader.GetString(8),
                                wuid = reader.IsDBNull(9) ? "" : reader.GetString(9),
                                wdate = reader.IsDBNull(10) ? (DateTime?)null : reader.GetDateTime(10),
                                project = reader.IsDBNull(11) ? "" : reader.GetInt32(11).ToString(),
                                pidx = reader.IsDBNull(12) ? -1 : reader.GetInt32(12),
                                gcode = reader.IsDBNull(13) ? "" : reader.GetString(13),
                                close = reader.IsDBNull(14) ? false : reader.GetBoolean(14),
                                remark = reader.IsDBNull(15) ? "" : reader.GetString(15),
                                root_idx = reader.IsDBNull(16) ? (int?)null : reader.GetInt32(16),
                                depth = reader.IsDBNull(17) ? 0 : reader.GetInt32(17),
                                sort_order = reader.IsDBNull(18) ? 0 : reader.GetInt32(18),
                                thread_path = reader.IsDBNull(19) ? "" : reader.GetString(19),
                                is_comment = reader.IsDBNull(20) ? false : reader.GetBoolean(20),
                                reply_count = reader.IsDBNull(21) ? 0 : reader.GetInt32(21),
                                wuid_name = reader.IsDBNull(22) ? "" : reader.GetString(22)
                            });
                        }
                    }

                    return JsonConvert.SerializeObject(new { Success = true, Data = list });
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 게시판 상세 조회
        /// </summary>
        public string Board_GetDetail(int idx)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;//Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    var cmd = new SqlCommand(@"
                        SELECT idx, bidx, header, cate, title, contents, [file], guid, url, wuid, wdate, project, pidx, gcode, [close], remark,
                               root_idx, depth, sort_order, thread_path, is_comment, reply_count,
                               dbo.getUserName(wuid) AS wuid_name
                        FROM EETGW_Board WITH (nolock)
                        WHERE idx = @idx AND gcode = @gcode", conn);

                    cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
                    cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode;

                    using (var reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            var data = new
                            {
                                idx = reader.GetInt32(0),
                                bidx = reader.GetInt32(1),
                                header = reader.IsDBNull(2) ? "" : (reader.GetBoolean(2) ? "공지" : ""),
                                cate = reader.IsDBNull(3) ? "" : reader.GetString(3),
                                title = reader.IsDBNull(4) ? "" : reader.GetString(4),
                                contents = reader.IsDBNull(5) ? "" : reader.GetString(5),
                                file = reader.IsDBNull(6) ? "" : reader.GetString(6),
                                guid = reader.IsDBNull(7) ? "" : reader.GetString(7),
                                url = reader.IsDBNull(8) ? "" : reader.GetString(8),
                                wuid = reader.IsDBNull(9) ? "" : reader.GetString(9),
                                wdate = reader.IsDBNull(10) ? (DateTime?)null : reader.GetDateTime(10),
                                project = reader.IsDBNull(11) ? "" : reader.GetInt32(11).ToString(),
                                pidx = reader.IsDBNull(12) ? -1 : reader.GetInt32(12),
                                gcode = reader.IsDBNull(13) ? "" : reader.GetString(13),
                                close = reader.IsDBNull(14) ? false : reader.GetBoolean(14),
                                remark = reader.IsDBNull(15) ? "" : reader.GetString(15),
                                root_idx = reader.IsDBNull(16) ? (int?)null : reader.GetInt32(16),
                                depth = reader.IsDBNull(17) ? 0 : reader.GetInt32(17),
                                sort_order = reader.IsDBNull(18) ? 0 : reader.GetInt32(18),
                                thread_path = reader.IsDBNull(19) ? "" : reader.GetString(19),
                                is_comment = reader.IsDBNull(20) ? false : reader.GetBoolean(20),
                                reply_count = reader.IsDBNull(21) ? 0 : reader.GetInt32(21),
                                wuid_name = reader.IsDBNull(22) ? "" : reader.GetString(22)
                            };

                            return JsonConvert.SerializeObject(new { Success = true, Data = data });
                        }
                        else
                        {
                            return JsonConvert.SerializeObject(new { Success = false, Message = "데이터를 찾을 수 없습니다." });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 게시판 추가
        /// </summary>
        public string Board_Add(int bidx, string header, string cate, string title, string contents)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    var cmd = new SqlCommand(@"
                        DECLARE @newIdx INT;
                        INSERT INTO EETGW_Board (bidx, header, cate, title, contents, wuid, wdate, gcode, depth, root_idx, thread_path, is_comment)
                        VALUES (@bidx, @header, @cate, @title, @contents, @wuid, GETDATE(), @gcode, 0, NULL, NULL, 0);
                        SET @newIdx = SCOPE_IDENTITY();
                        UPDATE EETGW_Board SET root_idx = @newIdx, thread_path = CAST(@newIdx AS VARCHAR(20)) WHERE idx = @newIdx;
                        SELECT @newIdx;", conn);

                    cmd.Parameters.Add("@bidx", SqlDbType.Int).Value = bidx;
                    cmd.Parameters.Add("@header", SqlDbType.NVarChar).Value = string.IsNullOrEmpty(header) ? (object)DBNull.Value : header;
                    cmd.Parameters.Add("@cate", SqlDbType.NVarChar).Value = string.IsNullOrEmpty(cate) ? (object)DBNull.Value : cate;
                    cmd.Parameters.Add("@title", SqlDbType.NVarChar).Value = title;
                    cmd.Parameters.Add("@contents", SqlDbType.NVarChar).Value = contents;
                    cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no;
                    cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode;

                    var newIdx = Convert.ToInt32(cmd.ExecuteScalar());

                    return JsonConvert.SerializeObject(new { Success = true, Message = "등록되었습니다.", Data = new { idx = newIdx } });
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 게시판 수정
        /// </summary>
        public string Board_Edit(int idx, string header, string cate, string title, string contents)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    // 권한 확인: 작성자 본인이거나 레벨 9 이상만 수정 가능
                    var checkCmd = new SqlCommand("SELECT wuid FROM EETGW_Board WHERE idx = @idx", conn);
                    checkCmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
                    var originalWuid = checkCmd.ExecuteScalar()?.ToString();

                    if (originalWuid != info.Login.no && info.Login.level < 9)
                    {
                        return JsonConvert.SerializeObject(new { Success = false, Message = "수정 권한이 없습니다." });
                    }

                    var cmd = new SqlCommand(@"
                        UPDATE EETGW_Board
                        SET header = @header, cate = @cate, title = @title, contents = @contents
                        WHERE idx = @idx", conn);

                    cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
                    cmd.Parameters.Add("@header", SqlDbType.NVarChar).Value = string.IsNullOrEmpty(header) ? (object)DBNull.Value : header;
                    cmd.Parameters.Add("@cate", SqlDbType.NVarChar).Value = string.IsNullOrEmpty(cate) ? (object)DBNull.Value : cate;
                    cmd.Parameters.Add("@title", SqlDbType.NVarChar).Value = title;
                    cmd.Parameters.Add("@contents", SqlDbType.NVarChar).Value = contents;

                    var affected = cmd.ExecuteNonQuery();

                    if (affected > 0)
                    {
                        return JsonConvert.SerializeObject(new { Success = true, Message = "수정되었습니다." });
                    }
                    else
                    {
                        return JsonConvert.SerializeObject(new { Success = false, Message = "수정할 데이터를 찾을 수 없습니다." });
                    }
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 게시판 삭제
        /// </summary>
        public string Board_Delete(int idx)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    // 권한 확인: 작성자 본인이거나 레벨 9 이상만 삭제 가능
                    var checkCmd = new SqlCommand("SELECT wuid FROM EETGW_Board WHERE idx = @idx", conn);
                    checkCmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
                    var originalWuid = checkCmd.ExecuteScalar()?.ToString();

                    if (originalWuid != info.Login.no && info.Login.level < 9)
                    {
                        return JsonConvert.SerializeObject(new { Success = false, Message = "삭제 권한이 없습니다." });
                    }

                    // 답글 존재 여부 확인 (is_comment=false인 답글만)
                    var replyCheckCmd = new SqlCommand(@"
                        SELECT COUNT(*) 
                        FROM EETGW_Board 
                        WHERE root_idx = @idx AND depth > 0 AND (is_comment IS NULL OR is_comment = 0)", conn);
                    replyCheckCmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
                    var replyCount = (int)replyCheckCmd.ExecuteScalar();

                    if (replyCount > 0)
                    {
                        return JsonConvert.SerializeObject(new { Success = false, Message = "답글이 있는 게시글은 삭제할 수 없습니다. 답글을 먼저 삭제해주세요." });
                    }

                    var cmd = new SqlCommand("DELETE FROM EETGW_Board WHERE idx = @idx", conn);
                    cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;

                    var affected = cmd.ExecuteNonQuery();

                    if (affected > 0)
                    {
                        return JsonConvert.SerializeObject(new { Success = true, Message = "삭제되었습니다." });
                    }
                    else
                    {
                        return JsonConvert.SerializeObject(new { Success = false, Message = "삭제할 데이터를 찾을 수 없습니다." });
                    }
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 댓글 목록 조회 (is_comment=true만)
        /// </summary>
        public string Board_GetReplies(int rootIdx)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    var cmd = new SqlCommand(@"
                        SELECT idx, bidx, header, cate, title, contents, [file], guid, url, wuid, wdate, project, pidx, gcode, [close], remark,
                               root_idx, depth, sort_order, thread_path, is_comment, reply_count,
                               dbo.getUserName(wuid) AS wuid_name
                        FROM EETGW_Board WITH (nolock)
                        WHERE root_idx = @rootIdx AND depth > 0 AND is_comment = 1
                        ORDER BY thread_path, wdate", conn);

                    cmd.Parameters.Add("@rootIdx", SqlDbType.Int).Value = rootIdx;

                    var list = new List<object>();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            list.Add(new
                            {
                                idx = reader.GetInt32(0),
                                bidx = reader.GetInt32(1),
                                header = reader.IsDBNull(2) ? "" : (reader.GetBoolean(2) ? "공지" : ""),
                                cate = reader.IsDBNull(3) ? "" : reader.GetString(3),
                                title = reader.IsDBNull(4) ? "" : reader.GetString(4),
                                contents = reader.IsDBNull(5) ? "" : reader.GetString(5),
                                file = reader.IsDBNull(6) ? "" : reader.GetString(6),
                                guid = reader.IsDBNull(7) ? "" : reader.GetString(7),
                                url = reader.IsDBNull(8) ? "" : reader.GetString(8),
                                wuid = reader.IsDBNull(9) ? "" : reader.GetString(9),
                                wdate = reader.IsDBNull(10) ? (DateTime?)null : reader.GetDateTime(10),
                                project = reader.IsDBNull(11) ? "" : reader.GetInt32(11).ToString(),
                                pidx = reader.IsDBNull(12) ? -1 : reader.GetInt32(12),
                                gcode = reader.IsDBNull(13) ? "" : reader.GetString(13),
                                close = reader.IsDBNull(14) ? false : reader.GetBoolean(14),
                                remark = reader.IsDBNull(15) ? "" : reader.GetString(15),
                                root_idx = reader.IsDBNull(16) ? (int?)null : reader.GetInt32(16),
                                depth = reader.IsDBNull(17) ? 0 : reader.GetInt32(17),
                                sort_order = reader.IsDBNull(18) ? 0 : reader.GetInt32(18),
                                thread_path = reader.IsDBNull(19) ? "" : reader.GetString(19),
                                is_comment = reader.IsDBNull(20) ? false : reader.GetBoolean(20),
                                reply_count = reader.IsDBNull(21) ? 0 : reader.GetInt32(21),
                                wuid_name = reader.IsDBNull(22) ? "" : reader.GetString(22)
                            });
                        }
                    }

                    return JsonConvert.SerializeObject(new { Success = true, Data = list });
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }

        /// <summary>
        /// 댓글/답글 추가
        /// </summary>
        public string Board_AddReply(int rootIdx, int pidx, string title, string contents, bool isComment)
        {
            try
            {
                if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
                {
                    return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
                }

                var connStr = Project.Properties.Settings.Default.CS;
                using (var conn = new SqlConnection(connStr))
                {
                    conn.Open();

                    // 부모 글 정보 조회
                    var parentCmd = new SqlCommand(@"
                        SELECT bidx, gcode, depth, thread_path 
                        FROM EETGW_Board 
                        WHERE idx = @pidx", conn);
                    parentCmd.Parameters.Add("@pidx", SqlDbType.Int).Value = pidx;

                    int bidx = 0;
                    string gcode = "";
                    int parentDepth = 0;
                    string parentThreadPath = "";

                    using (var reader = parentCmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            bidx = reader.GetInt32(0);
                            gcode = reader.IsDBNull(1) ? "" : reader.GetString(1);
                            parentDepth = reader.IsDBNull(2) ? 0 : reader.GetInt32(2);
                            parentThreadPath = reader.IsDBNull(3) ? "" : reader.GetString(3);
                        }
                        else
                        {
                            return JsonConvert.SerializeObject(new { Success = false, Message = "부모 글을 찾을 수 없습니다." });
                        }
                    }

                    // 댓글/답글 삽입
                    var cmd = new SqlCommand(@"
                        DECLARE @newIdx INT;
                        INSERT INTO EETGW_Board (bidx, cate, title, contents, wuid, wdate, gcode, pidx, root_idx, depth, is_comment)
                        VALUES (@bidx, NULL, @title, @contents, @wuid, GETDATE(), @gcode, @pidx, @rootIdx, @depth, @isComment);
                        SET @newIdx = SCOPE_IDENTITY();
                        UPDATE EETGW_Board SET thread_path = @parentThreadPath + '/' + CAST(@newIdx AS VARCHAR(20)) WHERE idx = @newIdx;
                        SELECT @newIdx;", conn);

                    cmd.Parameters.Add("@bidx", SqlDbType.Int).Value = bidx;
                    cmd.Parameters.Add("@title", SqlDbType.NVarChar).Value = string.IsNullOrEmpty(title) ? (object)DBNull.Value : title;
                    cmd.Parameters.Add("@contents", SqlDbType.NVarChar).Value = contents;
                    cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no;
                    cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = string.IsNullOrEmpty(gcode) ? info.Login.gcode : gcode;
                    cmd.Parameters.Add("@pidx", SqlDbType.Int).Value = pidx;
                    cmd.Parameters.Add("@rootIdx", SqlDbType.Int).Value = rootIdx;
                    cmd.Parameters.Add("@depth", SqlDbType.Int).Value = parentDepth + 1;
                    cmd.Parameters.Add("@isComment", SqlDbType.Bit).Value = isComment;
                    cmd.Parameters.Add("@parentThreadPath", SqlDbType.VarChar).Value = parentThreadPath;

                    var newIdx = Convert.ToInt32(cmd.ExecuteScalar());

                    return JsonConvert.SerializeObject(new { Success = true, Message = "댓글이 등록되었습니다.", Data = new { idx = newIdx } });
                }
            }
            catch (Exception ex)
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
            }
        }
    }
}
