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

namespace OpcUaManager.Controllers;

[ApiController]
[Route("api/session")]
[Produces("application/json")]
public class SessionController : ControllerBase
{
    private readonly OpcSessionService _sessionSvc;
    private readonly ILogger<SessionController> _logger;

    public SessionController(OpcSessionService sessionSvc, ILogger<SessionController> logger)
    {
        _sessionSvc = sessionSvc;
        _logger     = logger;
    }

    /// <summary>
    /// OPC UA 서버에 연결합니다.
    /// </summary>
    /// <remarks>
    /// Sample request:
    ///
    ///     POST /api/session/connect
    ///     {
    ///         "serverIp": "192.168.0.20",
    ///         "port": 4840,
    ///         "userName": "mngr",
    ///         "password": "mngr",
    ///         "securityPolicy": "Basic256Sha256",
    ///         "sessionTimeoutMs": 60000,
    ///         "pfxPath": "pki/own/certs/OpcTestClient.pfx",
    ///         "pfxPassword": "",
    ///         "applicationName": "OpcTestClient",
    ///         "applicationUri": "urn:dbsvr:OpcTestClient"
    ///     }
    /// </remarks>
    [HttpPost("connect")]
    [ProducesResponseType(typeof(ConnectResult), 200)]
    [ProducesResponseType(typeof(ApiError), 400)]
    public async Task<IActionResult> Connect([FromBody] ConnectRequest req)
    {
        if (string.IsNullOrWhiteSpace(req.ServerIp))
            return BadRequest(new ApiError { Error = "ServerIp 는 필수입니다." });

        _logger.LogInformation("연결 요청: {Ip}:{Port}", req.ServerIp, req.Port);
        var result = await _sessionSvc.ConnectAsync(req);

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

    /// <summary>현재 OPC UA 세션을 종료합니다.</summary>
    [HttpPost("disconnect")]
    [ProducesResponseType(200)]
    public async Task<IActionResult> Disconnect()
    {
        await _sessionSvc.DisconnectAsync();
        return Ok(new { Message = "세션 종료 완료" });
    }

    /// <summary>현재 세션 상태를 반환합니다.</summary>
    [HttpGet("status")]
    [ProducesResponseType(200)]
    public IActionResult Status()
        => Ok(new
        {
            IsConnected = _sessionSvc.IsConnected,
            SessionId   = _sessionSvc.SessionId
        });
}
