using DamageAssesment.Api.DocuLinks.Db;
using DamageAssesment.Api.DocuLinks.Interfaces;
using DamageAssesment.Api.DocuLinks.Models;
using DamageAssesment.Api.DocuLinks.Providers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace DamageAssesment.Api.DocuLinks.Controllers
{
    [ApiController]
    public class DoculinkController : ControllerBase
    {
        private readonly IDoculinkProvider documentsProvider;
        private readonly IUploadService uploadService;
        private readonly IAzureBlobService azureBlobService;

        public DoculinkController(IDoculinkProvider documentsProvider, IUploadService uploadService)
        {

            this.documentsProvider = documentsProvider;
            this.uploadService = uploadService;

        }
        /// <summary>
        /// Get all Doculink type.
        /// </summary>
        [HttpGet]
        [Authorize(Roles = "admin")]
        [Route("doculinks/types")]
        [Route("doculinks/types/{language:alpha}")]
        public async Task<IActionResult> GetLinkTypesAsync(string? language)
        {
            var result = await this.documentsProvider.GetLinkTypesAsync(language);
            if (result.IsSuccess)
            {
                return Ok(result.LinkTypes);
            }
            return NoContent();
        }
        /// <summary>
        /// Get a Doculink type by id.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpGet]
        [Route("doculinks/types/{id}")]
        [Route("doculinks/types/{id}/{language:alpha}")]
        public async Task<IActionResult> GetLinkTypeAsync(int id, string? language)
        {
            var result = await this.documentsProvider.GetLinkTypeAsync(id, language);
            if (result.IsSuccess)
            {
                return Ok(result.LinkType);
            }
            return NotFound();
        }
        /// <summary>
        /// Update a existing Doculink type.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpPut]
        [Route("doculinks/types/{id}")]
        public async Task<IActionResult> UpdateLinkType(int id, Models.LinkType linkType)
        {
            if (linkType != null)
            {
                var result = await this.documentsProvider.UpdateLinkTypeAsync(id, linkType);
                if (result.IsSuccess)
                {
                    return Ok(result.LinkType);
                }
                if (result.ErrorMessage == "Not Found")
                    return NotFound(result.ErrorMessage);

                return BadRequest(result.ErrorMessage);
            }
            return CreatedAtRoute("DefaultApi", new { id = linkType.Id }, linkType);
        }
        /// <summary>
        /// Create a new Doculink type.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpPost]
        [Route("doculinks/types")]
        public async Task<IActionResult> CreateLinkType(Models.LinkType linkType)
        {
            if (linkType != null)
            {
                var result = await this.documentsProvider.PostLinkTypeAsync(linkType);
                if (result.IsSuccess)
                {
                    return Ok(result.LinkType);
                }
                return BadRequest(result.ErrorMessage);
            }
            return CreatedAtRoute("DefaultApi", new { id = linkType.Id }, linkType);
        }
        /// <summary>
        /// Delete a  existing Doculink type by id.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpDelete]
        [Route("doculinks/types/{id}")]
        public async Task<IActionResult> DeleteLinkType(int id)
        {
            var result = await this.documentsProvider.DeleteLinkTypeAsync(id);
            if (result.IsSuccess)
            {
                return Ok(result.LinkType);
            }
            return NotFound();
        }
        /// <summary>
        /// download an existing attachment.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpGet("doculinks/download/{id}")]
        public async Task<IActionResult> downloadfile(int id)
        {
            try
            {
                var result = await this.documentsProvider.GetDownloadAttachmentAsync(id);
                if (!result.IsSuccess)
                    return NotFound();
                string path = await uploadService.GetFile(result.DoculinkAttachments.Path);
                if (path == null)
                    return NotFound();
                var contentType = GetContentType(result.DoculinkAttachments.docName);
                if (contentType == "application/octet-stream")
                    return PhysicalFile(path, contentType, result.DoculinkAttachments.docName);
                return PhysicalFile(path, contentType, enableRangeProcessing: true);
            }
            catch (Exception ex)
            {
                // Handle the exception here or log it
                return StatusCode(500, "An error occurred: " + ex.Message);
            }
            //try
            //{
            //    var result = await this.documentsProvider.GetDownloadAttachmentAsync(id);
            //    if (!result.IsSuccess)
            //        return NotFound();
            //    byte[] fileContent = await uploadService.DownloadFile(result.DoculinkAttachments.Path);
            //    if (fileContent == null || fileContent.Length == 0)
            //        return NotFound();
            //    var contentType = "application/octet-stream";
            //    return File(fileContent, contentType, result.DoculinkAttachments.docName);
            //}
            //catch (Exception ex)
            //{
            //    // Handle the exception here or log it
            //    return StatusCode(500, "An error occurred: " + ex.Message);
            //}
        }
        private string GetContentType(string fileName)
        {
            // You can add more content types based on the file extensions
            switch (Path.GetExtension(fileName).ToLower())
            {
                //case ".txt":
                //    return "text/plain";
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".png":
                    return "image/png";
                case ".gif":
                    return "image/gif";
                case ".bmp":
                    return "image/bmp";
                case ".webp":
                    return "image/webp";
                case ".csv":
                    return "text/csv";
                case ".pdf":
                    return "application/pdf";
                case ".docx":
                case ".doc":
                    return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                case ".xlsx":
                case ".xls":
                    return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                // Add more cases as needed
                default:
                    return "application/octet-stream";
            }
        }
        /// <summary>
        /// Get all Doculink.
        /// </summary>
        
        [Authorize(Roles = "admin")]
        [Route("doculinks")]
        [Route("doculinks/{linktype:alpha}")]
        [Route("doculinks/{linktype:alpha}/{language:alpha}")]
        [HttpGet]
        public async Task<IActionResult> GetDocumentsAsync(string? linktype, string? language, bool? isactive)
        {
            var result = await this.documentsProvider.GetdocumentsByLinkAsync(linktype, language, isactive);
            if (result.IsSuccess)
            {
                return Ok(result.documents);
            }
            return NoContent();
        }
        /// <summary>
        /// Get all active Doculink.
        /// </summary>
        [Route("doculinks/active")]
        [Route("doculinks/active/{linktype:alpha}")]
        [Route("doculinks/active/{linktype:alpha}/{language:alpha}")]
        [HttpGet]
        public async Task<IActionResult> GetDocumentsByActiveAsync(string? linktype, string? language)
        {
            var result = await this.documentsProvider.GetdocumentsByLinkAsync(linktype, language, true);
            if (result.IsSuccess)
            {
                return Ok(result.documents);
            }
            return NoContent();
        }
        /// <summary>
        /// Get all active Doculink.
        /// </summary>
        [Route("doculinks/active/{linktypeid:int}")]
        [Route("doculinks/active/{linktypeid:int}/{language:alpha}")]
        [HttpGet]
        public async Task<IActionResult> GetDocumentsByActiveLinkTypeIdAsync(int? linktypeid, string? language)
        {
            var result = await this.documentsProvider.GetdocumentsByLinkTypeIdAsync(linktypeid, language, true);
            if (result.IsSuccess)
            {
                return Ok(result.documents);
            }
            return NoContent();
        }
        /// <summary>
        /// Get a Doculink by id.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpGet]
        [Route("doculinks/{id}")]
        [Route("doculinks/{id}/{linktype:alpha}")]
        [Route("doculinks/{id}/{linktype:alpha}/{language:alpha}")]
        public async Task<IActionResult> GetDocumentAsync(int id, string? linktype, string? language)
        {
            var result = await this.documentsProvider.GetDocumentAsync(id, linktype, language);
            if (result.IsSuccess)
            {
                return Ok(result.Document);
            }
            return NotFound();
        }
        /// <summary>
        /// update existing doclink.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpPut]
        [Route("doculinks/{id}")]
        public async Task<IActionResult> UpdateDocument(int id, ReqDoculink documentInfo)
        {
            if (documentInfo != null)
            {
                var dbdoc = await this.documentsProvider.GetDocumentByidAsync(id);
                if (dbdoc.IsSuccess)
                {
                    var documents = await this.documentsProvider.GetDocumentCounter();
                    Models.Doculink DocuLink = uploadService.UpdateDocuments(documents.counter, dbdoc.Document, documentInfo);
                    var result = await this.documentsProvider.UpdateDocumentAsync(id, DocuLink);
                    if (result.IsSuccess)
                    {
                        return Ok(result.Document);
                    }
                    return NoContent();
                }
                return NotFound();
            }
            return BadRequest(documentInfo);
        }
        /// <summary>
        /// update existing doclink isactive field.
        /// </summary>
        [HttpPut]
        [Route("doculinks/{id}/{isactive}")]
        public async Task<IActionResult> UpdateIsActiveDocument(int id, bool isactive)
        {
            var result = await this.documentsProvider.UpdateDocumentAsync(id, isactive);
            if (result.IsSuccess)
            {
                return Ok(result.Document);
            }
            return NotFound();
        }
        /// <summary>
        /// Create new doclink.
        /// </summary>
       // [Authorize(Roles = "admin")]
        [HttpPost]
        [Route("doculinks")]
        public async Task<IActionResult> CreateDocument(ReqDoculink documentInfo)
        {
            try
            {
                if (documentInfo != null)
                {
                    var documents = await this.documentsProvider.GetDocumentCounter();
                    Models.Doculink DocuLink = uploadService.UploadDocument(documents.counter, documentInfo);
                    var result = await this.documentsProvider.PostDocumentAsync(DocuLink);
                    if (result.IsSuccess)
                    {
                        return Ok(result.Document);
                    }
                    return NoContent();
                }
                return BadRequest(documentInfo);
            }
            catch (Exception ex)
            {
                return BadRequest($"Internal server error: {ex}");
            }
        }
        /// <summary>
        /// Delete Doculink by id.
        /// </summary>
        [Authorize(Roles = "admin")]
        [HttpDelete]
        [Route("doculinks/{id}")]
        public async Task<IActionResult> DeleteDocument(int id)
        {
            // database soft delete
            var result = await this.documentsProvider.DeleteDocumentAsync(id);
            if (result.IsSuccess)
            {
                // deleting file from folder
                foreach (var item in result.Document.doclinksAttachments)
                {
                    uploadService.Movefile(item.Path);
                }
                return Ok(result.Document);
            }
            return NotFound();
        }

    }
}