using System;
using System.Threading.Tasks;
using Azure.Storage.Blobs.Models;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using OpenCvSharp;
using squirrowse.core;
using squirrowse.db;

namespace squirrowse.web.Cognitive
{
    public class AzureCV : IAzureCV
    {
        private readonly Bloob _blob;
        private readonly ComputerVisionClient _client;
        private readonly DbContext _db;

        public AzureCV(DbContext db, Bloob blob)
        {
            _blob = blob;
            _db = db;
            _client = new ComputerVisionClient(new ApiKeyServiceClientCredentials("64b5ed98d11d41b395e270424088ec83"))
            {
                Endpoint =
                    "https://squirrowse.cognitiveservices.azure.com/"
            };
        }

        public async Task<DetectResult> GetObjects(Mat frame)
        {
            var response = await _client.DetectObjectsInStreamAsync(frame.ToMemoryStream());
            var blobref =
                _blob.Container.GetBlobClient(
                    $"{DateTime.Now.ToShortDateString()}-{DateTime.Now.ToLongTimeString()}.png");

            await blobref.UploadAsync(frame.ToMemoryStream(), new BlobHttpHeaders {ContentType = "image/png"});

            var t = new Frame(frame, response.Objects, blobref.Uri);
            _db.GetFrameCollection.Insert(t);
            return response;
        }

        public Task<Mat> DrawResults(Mat frame, DetectResult results)
        {
            foreach (var result in results.Objects)
            {
                Cv2.PutText(frame, result.ObjectProperty.ToUpper(),
                    new Point(result.Rectangle.X, result.Rectangle.Y + result.Rectangle.H * 0.9),
                    HersheyFonts.HersheyComplex, 0.9f, Scalar.Yellow);

                frame.Rectangle(
                    new Rect(result.Rectangle.X, result.Rectangle.Y, result.Rectangle.W, result.Rectangle.H),
                    Scalar.White, 2);
            }

            return Task.FromResult(frame);
        }

        public async Task<ImageDescription> GetDescription(Mat frame)
        {
            return await _client.DescribeImageInStreamAsync(frame.ToMemoryStream());
        }
    }
}