using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace OI.Metrology.Server.ApiControllers;

using OI.Metrology.Server.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services;
using System.Data;
using System.Text.Json;

[Route("api/[controller]")]
public class ToolTypesController : Controller, IToolTypesController<IActionResult>
{
    // this controller powers the bulk of the UI
    // it is named after the /api/tooltypes prefix
    // the URL pattern is RESTful and the tool type is the root of every request

    private readonly AppSettings _AppSettings;
    private readonly IMetrologyRepository _MetrologyRepo;
    private readonly IAttachmentsService _AttachmentsService;
    private readonly IToolTypesRepository _ToolTypesRepository;

    public ToolTypesController(AppSettings appSettings, IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, IToolTypesRepository toolTypesRepository)
    {
        _AppSettings = appSettings;
        _MetrologyRepo = metrologyRepository;
        _AttachmentsService = attachmentsService;
        _ToolTypesRepository = toolTypesRepository;
    }

    [HttpGet]
    public IActionResult Index() =>
        Json(_ToolTypesRepository.Index(_MetrologyRepo), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });

    [HttpGet]
    [Route("{id}")]
    public IActionResult GetToolTypeMetadata(int id, string sortby = "") =>
        Json(_ToolTypesRepository.GetToolTypeMetadata(_MetrologyRepo, id, sortby), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });

    [HttpGet]
    [Route("{id}/headers")]
    public IActionResult GetHeaders(int id, [FromQuery] DateTime? datebegin, [FromQuery] DateTime? dateend, [FromQuery] int? page, [FromQuery] int? pagesize, [FromQuery] long? headerid)
    {
        Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetHeaders(_MetrologyRepo, id, datebegin, dateend, page, pagesize, headerid);
        string json = JsonConvert.SerializeObject(r);
        return Content(json);
    }

    [HttpGet]
    [Route("{id}/headertitles")]
    public IActionResult GetHeaderTitles(int id, [FromQuery] int? page, [FromQuery] int? pagesize) =>
        Json(_ToolTypesRepository.GetHeaderTitles(_MetrologyRepo, id, page, pagesize), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });

    [HttpGet]
    [Route("{id}/headers/{headerid}/fields")]
    public IActionResult GetHeaderFields(int id, long headerid) =>
        Json(_ToolTypesRepository.GetHeaderFields(_MetrologyRepo, id, headerid), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });

    [HttpGet]
    [Route("{id}/headers/{headerid}/data")]
    public IActionResult GetData(int id, long headerid)
    {
        Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetData(_MetrologyRepo, id, headerid);
        string json = JsonConvert.SerializeObject(r);
        return Content(json);
    }

    [HttpGet]
    [Route("{toolTypeId}/export")]
    public IActionResult GetExportData(int toolTypeId, [FromQuery] DateTime? datebegin, [FromQuery] DateTime? dateend)
    {
        Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetExportData(_MetrologyRepo, toolTypeId, datebegin, dateend);
        string json = JsonConvert.SerializeObject(r);
        return Content(json);
    }

    [HttpGet]
    [Route("{toolTypeId}/csv")]
    public IActionResult GetCSVExport(int toolTypeId, [FromQuery] DateTime? datebegin, [FromQuery] DateTime? dateend, [FromQuery] string? filename)
    {
        byte[] r = _ToolTypesRepository.GetCSVExport(_MetrologyRepo, toolTypeId, datebegin, dateend);
        return File(r, "application/octet-stream", filename);
    }

    [HttpGet]
    [Route("{toolTypeId}/{tabletype}/files/{attachmentId}/{filename}")]
    public IActionResult GetAttachment(int toolTypeId, string tabletype, string attachmentId, string filename)
    {
        (string? message, string? contenttype, Stream? stream) = _ToolTypesRepository.GetAttachment(_MetrologyRepo, _AttachmentsService, toolTypeId, tabletype, attachmentId, filename);
        if (message is not null)
            return Content(message);
        else if (contenttype is not null && stream is not null)
            return File(stream, contenttype);
        else
            throw new Exception();
    }

    [HttpPost]
    [Route("{toolTypeId}/headers/{headerid}/oiexport")]
    public IActionResult OIExport(int toolTypeId, long headerid)
    {
        string? message = _ToolTypesRepository.OIExport(_MetrologyRepo, _AttachmentsService, _AppSettings.AttachmentPath, _AppSettings.TableToPath, toolTypeId, headerid);
        if (message is null)
            return Ok(new { Message = "OK" });
        else
            return BadRequest(JsonConvert.SerializeObject(new { message }));
    }

}