using Microsoft.AspNetCore.Mvc;
using OpcUaManager.Models;
using OpcUaManager.Services;

namespace OpcUaManager.Controllers;

[ApiController]
[Route("api/database")]
[Produces("application/json")]
public class DatabaseController : ControllerBase
{
    private readonly DatabaseService _dbSvc;
    private readonly ILogger<DatabaseController> _logger;

    public DatabaseController(DatabaseService dbSvc, ILogger<DatabaseController> logger)
    {
        _dbSvc  = dbSvc;
        _logger = logger;
    }

    /// <summary>
    /// DB 연결을 테스트합니다.
    /// </summary>
    [HttpPost("test")]
    [ProducesResponseType(200)]
    [ProducesResponseType(typeof(ApiError), 400)]
    public async Task<IActionResult> Test([FromBody] DbWriteRequest req)
    {
        var (ok, msg) = await _dbSvc.TestConnectionAsync(req);
        return ok ? Ok(new { Message = msg })
                  : BadRequest(new ApiError { Error = "연결 실패", Detail = msg });
    }

    /// <summary>
    /// opc_history 테이블을 없으면 생성합니다.
    /// </summary>
    [HttpPost("init")]
    [ProducesResponseType(200)]
    [ProducesResponseType(typeof(ApiError), 400)]
    public async Task<IActionResult> Init([FromBody] DbWriteRequest req)
    {
        var (ok, msg) = await _dbSvc.EnsureTableAsync(req);
        return ok ? Ok(new { Message = msg })
                  : BadRequest(new ApiError { Error = "테이블 초기화 실패", Detail = msg });
    }

    /// <summary>
    /// OPC 태그를 지정 횟수만큼 읽어 DB에 저장합니다 (원본 5회 루프).
    /// </summary>
    /// <remarks>
    /// Sample request:
    ///
    ///     POST /api/database/write
    ///     {
    ///         "tagNodeId":  "ns=1;s=shinam:p-6102.hzset.fieldvalue",
    ///         "tagName":    "p-6102",
    ///         "count":      5,
    ///         "intervalMs": 2000,
    ///         "dbHost":     "localhost",
    ///         "dbName":     "opcdb",
    ///         "dbUser":     "postgres",
    ///         "dbPassword": "postgres"
    ///     }
    /// </remarks>
    [HttpPost("write")]
    [ProducesResponseType(typeof(DbWriteResult), 200)]
    [ProducesResponseType(typeof(ApiError), 400)]
    public async Task<IActionResult> Write([FromBody] DbWriteRequest req)
    {
        if (string.IsNullOrWhiteSpace(req.TagNodeId) || string.IsNullOrWhiteSpace(req.TagName))
            return BadRequest(new ApiError
            {
                Error  = "필수값 누락",
                Detail = "TagNodeId, TagName 은 필수입니다."
            });

        req.Count = Math.Clamp(req.Count, 1, 100);

        _logger.LogInformation("DB 저장 시작: {Tag} × {Count}회", req.TagName, req.Count);
        var result = await _dbSvc.WriteLoopAsync(req);

        return result.Success ? Ok(result)
            : BadRequest(new ApiError { Error = "저장 실패", Detail = result.Message });
    }

    /// <summary>
    /// opc_history 테이블의 최근 레코드를 조회합니다.
    /// </summary>
    [HttpPost("query")]
    [ProducesResponseType(typeof(DbQueryResult), 200)]
    [ProducesResponseType(typeof(ApiError), 400)]
    public async Task<IActionResult> Query([FromBody] DbWriteRequest req, [FromQuery] int limit = 100)
    {
        var result = await _dbSvc.QueryRecentAsync(req, limit);
        return result.Success ? Ok(result)
            : BadRequest(new ApiError { Error = "조회 실패", Detail = result.Message });
    }
}
