using Hc900Crawler.Core.Application.DTOs;
using Hc900Crawler.Core.Application.Interfaces;
using Hc900Crawler.Infrastructure.Mcp;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace Hc900Crawler.Web.Controllers;

/// <summary>
/// Text-to-SQL API 컨트롤러
/// 자연어 질의를 파싱하고 시계열 데이터를 조회합니다.
/// MCP (Model Context Protocol) 통합을 위한 엔드포인트를 제공합니다.
/// </summary>
[ApiController]
[Route("api/text-to-sql")]
public class TextToSqlController : ControllerBase
{
    private readonly ITextToSqlService _textToSqlService;
    private readonly IExperionDbService _dbService;
    private readonly IMcpService _mcpService;
    private readonly ILogger<TextToSqlController> _logger;

    public TextToSqlController(
        ITextToSqlService textToSqlService,
        IExperionDbService dbService,
        IMcpService mcpService,
        ILogger<TextToSqlController> logger)
    {
        _textToSqlService = textToSqlService;
        _dbService = dbService;
        _mcpService = mcpService;
        _logger = logger;
    }

    /// <summary>
    /// 자연어 질의를 SQL로 변환
    /// </summary>
    [HttpPost("parse")]
    public async Task<IActionResult> Parse([FromBody] NaturalLanguageQueryDto dto)
    {
        try
        {
            var sql = await _textToSqlService.ParseNaturalLanguageAsync(dto.Query);
            return Ok(new { success = true, sql });
        }
        catch (Exception ex)
        {
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP query_with_nl 도구 호출 - 자연어 → LLM SQL 생성 → 실행
    /// </summary>
    [HttpPost("query-nl")]
    public async Task<IActionResult> QueryWithNl([FromBody] NaturalLanguageQueryDto dto)
    {
        if (string.IsNullOrWhiteSpace(dto.Query))
            return BadRequest(new { success = false, error = "질문이 비어있음" });

        try
        {
            var result = await _mcpService.QueryWithNlAsync(dto.Query);
            if (!result.Success)
                return Ok(new { success = false, error = result.Error });

            try
            {
                var jsonData = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>?>(result.Data!);
                _logger.LogInformation("[TextToSql] query-nl 응답: success={Success}, data={Data}", jsonData?.GetType(), jsonData);
                
                // data 필드가 JSON 문자열일 수 있으므로 다시 디시리얼라이즈
                if (jsonData != null && jsonData.TryGetValue("data", out var dataObj) && dataObj is string dataString)
                {
                    _logger.LogInformation("[TextToSql] data 필드가 문자열임: {DataString}", dataString);
                    var parsedData = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>?>(dataString);
                    jsonData["data"] = parsedData!;
                }
                
                return Ok(new { success = true, data = jsonData });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "[TextToSql] query-nl JSON 디시리얼라이즈 실패: {Data}", result.Data);
                return Ok(new { success = true, data = result.Data });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] query-nl 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP 도구 목록 조회
    /// </summary>
    [HttpGet("tools")]
    public async Task<IActionResult> ListTools()
    {
        try
        {
            var tools = await _mcpService.ListToolsAsync();
            return Ok(new { success = true, tools });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] 도구 목록 조회 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP run_sql 도구 호출 - SQL 실행
    /// Text-to-SQL 엔진으로 생성된 SQL을 안전하게 실행
    /// </summary>
    [HttpPost("execute-mcp")]
    public async Task<IActionResult> ExecuteFromMcp([FromBody] SqlQueryDto dto)
    {
        if (string.IsNullOrWhiteSpace(dto.Sql))
        {
            return BadRequest(new { success = false, error = "SQL이 비어있음" });
        }

        try
        {
            // MCP run_sql 도구 호출
            var result = await _mcpService.RunSqlAsync(dto.Sql);

            if (!result.Success)
            {
                return Ok(new
                {
                    success = false,
                    error = result.Error
                });
            }

            // JSON 결과 반환 (쿼리 결과)
            try
            {
                var jsonData = System.Text.Json.JsonSerializer.Deserialize<object>(result.Data!);
                return Ok(new { success = true, data = jsonData });
            }
            catch
            {
                return Ok(new { success = true, data = result.Data });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] MCP 실행 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP query_pv_history 도구 호출 - 과거 값 히스토리 조회
    /// </summary>
    [HttpPost("query-history")]
    public async Task<IActionResult> QueryHistory([FromBody] HistoryQueryRequestDto dto)
    {
        try
        {
            var tagNames = dto.TagNames ?? [];
            var timeFrom = dto.From ?? DateTime.UtcNow.AddDays(-1).ToString("o");
            var timeTo = dto.To ?? DateTime.UtcNow.ToString("o");
            var limit = dto.Limit ?? 100;

            var result = await _mcpService.QueryPvHistoryAsync(
                tagNames,
                timeFrom,
                timeTo,
                limit
            );

            if (!result.Success)
            {
                return Ok(new
                {
                    success = false,
                    error = result.Error
                });
            }

            try
            {
                var jsonData = System.Text.Json.JsonSerializer.Deserialize<object>(result.Data!);
                return Ok(new
                {
                    success = true,
                    data = jsonData
                });
            }
            catch
            {
                return Ok(new
                {
                    success = true,
                    data = result.Data
                });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] History 쿼리 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP get_tag_metadata 도구 호출 - 태그 메타데이터 검색
    /// </summary>
    [HttpGet("tags/search")]
    public async Task<IActionResult> SearchTags([FromQuery] string query, [FromQuery] int? limit)
    {
        try
        {
            var tagLimit = limit ?? 10;
            var result = await _mcpService.GetTagMetadataAsync(query, tagLimit);

            if (!result.Success)
            {
                return Ok(new
                {
                    success = false,
                    error = result.Error
                });
            }

            try
            {
                var jsonData = System.Text.Json.JsonSerializer.Deserialize<object>(result.Data!);
                return Ok(new
                {
                    success = true,
                    data = jsonData
                });
            }
            catch
            {
                return Ok(new
                {
                    success = true,
                    data = result.Data
                });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] 태그 검색 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// MCP list_drawings 도구 호출 - 도면 목록 조회
    /// </summary>
    [HttpGet("drawings")]
    public async Task<IActionResult> ListDrawings([FromQuery] string? unitNo)
    {
        try
        {
            var result = await _mcpService.ListDrawingsAsync(unitNo);

            if (!result.Success)
            {
                return Ok(new
                {
                    success = false,
                    error = result.Error
                });
            }

            try
            {
                var jsonData = System.Text.Json.JsonSerializer.Deserialize<object>(result.Data!);
                return Ok(new
                {
                    success = true,
                    data = jsonData
                });
            }
            catch
            {
                return Ok(new
                {
                    success = true,
                    data = result.Data
                });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] 도면 목록 조회 실패");
            return Ok(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// 쿼리 제안 (자동 완성)
    /// </summary>
    [HttpGet("suggest")]
    public async Task<IActionResult> Suggest([FromQuery] string input = "")
    {
        var suggestions = await _textToSqlService.SuggestQueriesAsync(input);
        return Ok(new { success = true, suggestions });
    }

    /// <summary>
    /// 시계열 분석 (평균, 최대, 최소, 추세)
    /// </summary>
    [HttpPost("analyze")]
    public async Task<IActionResult> Analyze([FromBody] AnalyzeRequestDto dto)
    {
        var result = await _textToSqlService.AnalyzeAsync(dto);
        return Ok(new {
            success = result.Success,
            error = result.Error,
            tags = result.Tags?.Select(t => new {
                tagName = t.TagName,
                avg = t.Avg,
                mean = t.Mean,
                min = t.Min,
                max = t.Max,
                first = t.First,
                last = t.Last,
                pointCount = t.PointCount,
                stddev = t.StdDev,
                from = t.From,
                to = t.To
            }).ToList()
        });
    }

    /// <summary>
    /// 사용자 지정 간격으로 history 이력 조회
    /// history_table의 기본 저장 간격(60초)을 기반으로 사용자가 요청한 간격으로 데이터 집계
    /// </summary>
    [HttpPost("query-history-interval")]
    public async Task<IActionResult> QueryHistoryInterval([FromBody] HistoryIntervalQueryRequestDto dto)
    {
        try
        {
            var request = new HistoryIntervalQueryRequest(
                dto.TagNames,
                dto.From,
                dto.To,
                dto.Interval,
                dto.Limit);

            var result = await _dbService.QueryHistoryWithIntervalAsync(request);

            var response = new
            {
                success = true,
                tagNames = result.TagNames.ToList(),
                rows = result.Rows.Select(r => new
                {
                    timeBucket = r.TimeBucket,
                    values     = r.Values
                }).ToList(),
                baseIntervalSeconds = result.BaseIntervalSeconds,
                queryInterval = result.QueryInterval
            };

            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[TextToSql] QueryHistoryInterval 실패");
            return StatusCode(StatusCodes.Status500InternalServerError, new { success = false, error = ex.Message });
        }
    }
}
