using Hc900Crawler.Infrastructure.Hc900;
using Microsoft.AspNetCore.Mvc;

namespace Hc900Crawler.Web.Controllers;

[ApiController]
[Route("api/setup")]
public class SetupController : ControllerBase
{
    private readonly ControllerProcessManager _procMgr;
    private readonly Hc900RealtimeService _realtime;

    public SetupController(ControllerProcessManager procMgr, Hc900RealtimeService realtime)
    {
        _procMgr   = procMgr;
        _realtime = realtime;
    }

    /// <summary>전체 컨트롤러 상태 조회</summary>
    [HttpGet("controllers")]
    public IActionResult GetControllers()
    {
        var statuses = _procMgr.GetAllStatus();
        var connected = _realtime.ControllerConnected;
        return Ok(statuses.Select(s => new
        {
            s.ControllerId, s.Name, s.Running, s.Pid,
            s.Message, s.ControllerIp, s.GrpcPort, s.StartedAt,
            crawlerConnected = connected.GetValueOrDefault(s.ControllerId),
            pollCount = _realtime.PollCount,
        }));
    }

    /// <summary>게이트웨이 상태 + 최근 로그 (하위 호환)</summary>
    [HttpGet("gateway/status")]
    public IActionResult GetStatus()
    {
        var statuses = _procMgr.GetAllStatus();
        var first = statuses.FirstOrDefault() ?? new ControllerStatus();
        return Ok(new
        {
            running          = statuses.Any(s => s.Running),
            pid              = first.Pid,
            message          = string.Join(", ", statuses.Select(s => $"{s.ControllerId}:{s.Message}")),
            controllerIp     = string.Join(", ", statuses.Select(s => s.ControllerIp)),
            startedAt        = first.StartedAt,
            recentLog        = first.RecentLog,
            crawlerConnected = _realtime.IsConnected,
            crawlerPollCount = _realtime.PollCount,
            crawlerLastPoll  = _realtime.LastPollAt,
            controllers      = statuses.Select(s => new
            {
                s.ControllerId, s.Name, s.Running, s.Pid,
                s.Message, s.ControllerIp, s.GrpcPort, s.StartedAt,
                crawlerConnected = _realtime.ControllerConnected.GetValueOrDefault(s.ControllerId),
            }),
        });
    }

    /// <summary>설정 조회 (camelCase 보장)</summary>
    [HttpGet("config")]
    public IActionResult GetConfig()
    {
        _procMgr.ReloadConfig();
        var cfg = _procMgr.Config;
        return Ok(new
        {
            shared = new { cfg.Shared.BinaryPath, cfg.Shared.LdLibraryPath, cfg.Shared.LogDir },
            controllers = cfg.Controllers.Select(c => new
            {
                c.Id,
                c.Name,
                controllerIp    = c.ControllerIp,
                controllerPort  = c.ControllerPort,
                grpcPort        = c.GrpcPort,
                pollIntervalMs  = c.PollIntervalMs,
                registerMapPath = c.RegisterMapPath,
                c.Enabled,
            }),
        });
    }

    /// <summary>설정 저장</summary>
    [HttpPost("config")]
    public IActionResult SaveConfig([FromBody] MultiControllerConfig cfg)
    {
        try
        {
            ControllerProcessManager.SaveConfig(cfg);
            _procMgr.ReloadConfig();
            return Ok(new { success = true, message = "설정 저장 완료" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { success = false, message = ex.Message });
        }
    }

    /// <summary>특정 컨트롤러 시작</summary>
    [HttpPost("gateway/start")]
    public async Task<IActionResult> Start([FromQuery] string? id = null)
    {
        if (id != null)
        {
            var (ok, msg) = await _procMgr.StartAsync(id);
            return Ok(new { success = ok, message = msg });
        }
        var results = new List<object>();
        foreach (var ctrl in _procMgr.Config.Controllers.Where(c => c.Enabled))
        {
            var (ok, msg) = await _procMgr.StartAsync(ctrl.Id);
            results.Add(new { ctrl.Id, ok, msg });
        }
        return Ok(results);
    }

    /// <summary>특정 컨트롤러 중지</summary>
    [HttpPost("gateway/stop")]
    public async Task<IActionResult> Stop([FromQuery] string? id = null)
    {
        if (id != null)
        {
            var (ok, msg) = await _procMgr.StopAsync(id);
            return Ok(new { success = ok, message = msg });
        }
        var results = new List<object>();
        foreach (var ctrl in _procMgr.Config.Controllers)
        {
            var (ok, msg) = await _procMgr.StopAsync(ctrl.Id);
            results.Add(new { ctrl.Id, ok, msg });
        }
        return Ok(results);
    }

    /// <summary>설정 저장 + 게이트웨이 재시작</summary>
    [HttpPost("gateway/restart")]
    public async Task<IActionResult> Restart([FromBody] MultiControllerConfig? cfg, [FromQuery] string? id = null)
    {
        if (cfg != null) { ControllerProcessManager.SaveConfig(cfg); _procMgr.ReloadConfig(); }
        if (id != null)
        {
            await _procMgr.StopAsync(id);
            await Task.Delay(500);
            var (ok, msg) = await _procMgr.StartAsync(id);
            return Ok(new { success = ok, message = msg });
        }
        foreach (var ctrl in _procMgr.Config.Controllers)
            await _procMgr.StopAsync(ctrl.Id);
        await Task.Delay(500);
        var results = new List<object>();
        foreach (var ctrl in _procMgr.Config.Controllers.Where(c => c.Enabled))
        {
            var (ok, msg) = await _procMgr.StartAsync(ctrl.Id);
            results.Add(new { ctrl.Id, ok, msg });
        }
        return Ok(results);
    }

    /// <summary>게이트웨이 로그 조회</summary>
    [HttpGet("gateway/log")]
    public IActionResult GetLog([FromQuery] string? id = null, [FromQuery] int lines = 50)
    {
        var target = id ?? _procMgr.Config.Controllers.FirstOrDefault()?.Id;
        if (target == null) return Ok(new { log = Array.Empty<string>() });
        var status = _procMgr.GetStatus(target);
        return Ok(new { log = status.RecentLog.TakeLast(lines) });
    }
}
