using Microsoft.AspNetCore.Mvc;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using eSPJ.Models;
using eSPJ.Services;

namespace eSPJ.Controllers.SpjDriverUpstController
{
    [Route("upst/detail-penjemputan")]
    public class DetailPenjemputanController : Controller
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IConfiguration _configuration;
        private readonly DetailPenjemputanService _detailService;
        private readonly ILogger<DetailPenjemputanController> _logger;
        private readonly IWebHostEnvironment _env;

        public DetailPenjemputanController(
            IHttpClientFactory httpClientFactory, 
            IConfiguration configuration,
            DetailPenjemputanService detailService,
            ILogger<DetailPenjemputanController> logger,
            IWebHostEnvironment env)
        {
            _httpClientFactory = httpClientFactory;
            _configuration = configuration;
            _detailService = detailService;
            _logger = logger;
            _env = env;
        }

        private static string ResolveDraftKey(string? draftKey, string? sessionKey, string? spjDetailId = null, string? lokasiAngkutId = null)
        {
            var rawKey = !string.IsNullOrWhiteSpace(draftKey)
                ? draftKey
                : !string.IsNullOrWhiteSpace(sessionKey)
                    ? sessionKey
                    : $"non-tps-{spjDetailId}-{lokasiAngkutId}";

            return string.Concat((rawKey ?? string.Empty).Where(c => char.IsLetterOrDigit(c) || c == '-' || c == '_'));
        }

        private string GetUploadDirectory(string dateFolder)
        {
            var uploadDir = Path.Combine(_env.ContentRootPath, "uploads", "penjemputan", dateFolder);
            Directory.CreateDirectory(uploadDir);
            return uploadDir;
        }

        private static string BuildUploadUrl(string dateFolder, string fileName)
        {
            return $"/uploads/penjemputan/{dateFolder}/{fileName}";
        }

        [HttpGet("")]
        public IActionResult Index()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Index.cshtml");
        }
        [HttpGet("tanpa-tps")]
        public IActionResult TanpaTps()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/TanpaTps.cshtml");
        }

        [HttpGet("batal")]
        public IActionResult Batal()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Batal.cshtml");
        }

        [HttpGet("detail-batal")]
        public IActionResult DetailBatal()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/DetailBatal.cshtml");
        }

        [HttpGet("detail-selesai")]
        public IActionResult DetailSelesai()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/DetailSelesai.cshtml");
        }

        [HttpGet("detail-selesai-tanpa-tps")]
        public IActionResult DetailSelesaiTanpaTps()
        {
            return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/DetailSelesaiTanpaTps.cshtml");
        }

        [HttpPost("")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Submit([FromForm] DetailPenjemputanRequest request)
        {
            try
            {
                var result = await _detailService.SubmitPenjemputanAsync(request);
                
                if (result.Success)
                {
                    TempData["Success"] = result.Message;
                }
                else
                {
                    TempData["Error"] = result.Message;
                }
                
                return RedirectToAction(nameof(Index));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error submitting penjemputan data");
                TempData["Error"] = "Terjadi kesalahan saat menyimpan data.";
                return RedirectToAction(nameof(Index));
            }
        }

        [HttpPost("save-draft-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> SaveDraftNonTps([FromBody] DraftSaveRequest request)
        {
            if (request == null)
                return BadRequest(new DraftSaveResponse { Success = false, Message = "Request tidak valid." });

            request.DraftKey = ResolveDraftKey(request.DraftKey, request.SessionKey, request.SpjDetailId, request.LokasiAngkutId);
            request.SessionKey = request.DraftKey;
            if (string.IsNullOrWhiteSpace(request.DraftKey))
                return BadRequest(new DraftSaveResponse { Success = false, Message = "Draft key tidak valid." });

            var result = await _detailService.SaveDraftNonTpsAsync(request);
            return result.Success ? Ok(result) : StatusCode(500, result);
        }

        [HttpGet("load-draft-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> LoadDraftNonTps([FromQuery] string? draftKey = null, [FromQuery] string? sessionKey = null)
        {
            var key = ResolveDraftKey(draftKey, sessionKey);
            if (string.IsNullOrWhiteSpace(key))
                return Ok(new DraftLoadResponse { Success = true, HasDraft = false, Message = "Draft key kosong." });
            var result = await _detailService.LoadDraftNonTpsAsync(key);
            return Ok(result);
        }

        [HttpDelete("delete-draft-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> DeleteDraftNonTps([FromQuery] string? draftKey = null, [FromQuery] string? sessionKey = null)
        {
            var key = ResolveDraftKey(draftKey, sessionKey);
            if (string.IsNullOrWhiteSpace(key))
                return Ok(new { success = false });
            var ok = await _detailService.DeleteDraftNonTpsAsync(key);
            return Ok(new { success = ok });
        }

        [HttpPost("save-draft")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> SaveDraft([FromBody] DraftSaveRequest request)
        {
            if (request == null)
                return BadRequest(new DraftSaveResponse { Success = false, Message = "Request tidak valid." });

            request.DraftKey = ResolveDraftKey(request.DraftKey, request.SessionKey, request.SpjDetailId, request.LokasiAngkutId);
            request.SessionKey = request.DraftKey;
            if (string.IsNullOrWhiteSpace(request.DraftKey))
                return BadRequest(new DraftSaveResponse { Success = false, Message = "Draft key tidak valid." });

            var result = await _detailService.SaveDraftTpsAsync(request);
            return result.Success ? Ok(result) : StatusCode(500, result);
        }

        [HttpGet("load-draft")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> LoadDraft([FromQuery] string? draftKey = null, [FromQuery] string? sessionKey = null)
        {
            var key = ResolveDraftKey(draftKey, sessionKey);
            if (string.IsNullOrWhiteSpace(key))
                return Ok(new DraftLoadResponse { Success = true, HasDraft = false, Message = "Draft key kosong." });
            var result = await _detailService.LoadDraftTpsAsync(key);
            return Ok(result);
        }

        [HttpDelete("delete-draft")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> DeleteDraft([FromQuery] string? draftKey = null, [FromQuery] string? sessionKey = null)
        {
            var key = ResolveDraftKey(draftKey, sessionKey);
            if (string.IsNullOrWhiteSpace(key))
                return Ok(new { success = false });
            var ok = await _detailService.DeleteDraftTpsAsync(key);
            return Ok(new { success = ok });
        }


        [HttpPost("upload-foto-kedatangan-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoKedatanganNonTps(
            [FromForm] List<IFormFile>? FotoKedatangan,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] string? WaktuKedatangan,
            [FromForm] string? Latitude,
            [FromForm] string? Longitude,
            [FromForm] string? AlamatJalan)
        {
            if (FotoKedatangan == null || FotoKedatangan.Count == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var fileNames = new List<string>();
            foreach (var file in FotoKedatangan)
            {
                if (file.Length == 0) continue;
                var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
                var name = $"kedatangan_{Guid.NewGuid()}{ext}";
                var path = Path.Combine(uploadDir, name);
                await using var stream = new FileStream(path, FileMode.Create);
                await file.CopyToAsync(stream);
                fileNames.Add(name);
            }
            var fileUrls = fileNames.Select(n => BuildUploadUrl(dateFolder, n)).ToList();

            var resolvedDraftKey = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKey))
            {
                var loadResult = await _detailService.LoadDraftNonTpsAsync(resolvedDraftKey);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKey, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                draft.FotoKedatanganFileNames = fileUrls;
                draft.FotoKedatanganUploaded = true;
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                if (!string.IsNullOrWhiteSpace(WaktuKedatangan)) draft.WaktuKedatangan = WaktuKedatangan;
                if (!string.IsNullOrWhiteSpace(Latitude)) draft.Latitude = Latitude;
                if (!string.IsNullOrWhiteSpace(Longitude)) draft.Longitude = Longitude;
                if (!string.IsNullOrWhiteSpace(AlamatJalan)) draft.AlamatJalan = AlamatJalan;
                await _detailService.SaveDraftNonTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKey,
                    SessionKey = resolvedDraftKey,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = fileUrls,
                    FotoKedatanganUploaded = true,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = draft.FotoPetugasFileNames,
                    FotoPetugasUploaded = draft.FotoPetugasUploaded,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileNames, fileUrls, message = $"{fileNames.Count} foto kedatangan berhasil diupload." });
        }

        [HttpPost("upload-foto-timbangan-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoTimbanganNonTps(
            [FromForm] IFormFile? FotoTimbangan,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] int ItemIndex,
            [FromForm] string? JenisSampah,
            [FromForm] decimal Berat)
        {
            if (FotoTimbangan == null || FotoTimbangan.Length == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var ext = Path.GetExtension(FotoTimbangan.FileName).ToLowerInvariant();
            var jenisSafe = (JenisSampah ?? "residu").ToLowerInvariant();
            var beratStr = Berat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture).Replace('.', '_');
            var name = $"timbangan{ItemIndex + 1}-{jenisSafe}-{beratStr}{ext}";
            var filePath = Path.Combine(uploadDir, name);
            await using var stream = new FileStream(filePath, FileMode.Create);
            await FotoTimbangan.CopyToAsync(stream);
            var fileUrl = BuildUploadUrl(dateFolder, name);

            var resolvedDraftKey = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKey))
            {
                var loadResult = await _detailService.LoadDraftNonTpsAsync(resolvedDraftKey);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKey, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                while (draft.Timbangan.Count <= ItemIndex)
                    draft.Timbangan.Add(new DraftTimbanganItem());
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                draft.Timbangan[ItemIndex] = new DraftTimbanganItem
                {
                    FotoFileName = fileUrl,
                    JenisSampah = JenisSampah ?? "Residu",
                    Berat = Berat,
                    Uploaded = true
                };
                await _detailService.SaveDraftNonTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKey,
                    SessionKey = resolvedDraftKey,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = draft.FotoKedatanganFileNames,
                    FotoKedatanganUploaded = draft.FotoKedatanganUploaded,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = draft.FotoPetugasFileNames,
                    FotoPetugasUploaded = draft.FotoPetugasUploaded,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileName = name, fileUrl, message = $"Foto timbangan #{ItemIndex + 1} berhasil diupload." });
        }

        [HttpPost("upload-foto-petugas-non-tps")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoPetugasNonTps(
            [FromForm] List<IFormFile>? FotoPetugas,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] string? NamaPetugas)
        {
            if (FotoPetugas == null || FotoPetugas.Count == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var fileNames = new List<string>();
            foreach (var file in FotoPetugas)
            {
                if (file.Length == 0) continue;
                var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
                var name = $"petugas_{Guid.NewGuid()}{ext}";
                var path = Path.Combine(uploadDir, name);
                await using var stream = new FileStream(path, FileMode.Create);
                await file.CopyToAsync(stream);
                fileNames.Add(name);
            }
            var fileUrls = fileNames.Select(n => BuildUploadUrl(dateFolder, n)).ToList();

            var resolvedDraftKey = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKey))
            {
                var loadResult = await _detailService.LoadDraftNonTpsAsync(resolvedDraftKey);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKey, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                draft.FotoPetugasFileNames = fileUrls;
                draft.FotoPetugasUploaded = true;
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                if (!string.IsNullOrWhiteSpace(NamaPetugas)) draft.NamaPetugas = NamaPetugas;
                await _detailService.SaveDraftNonTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKey,
                    SessionKey = resolvedDraftKey,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = draft.FotoKedatanganFileNames,
                    FotoKedatanganUploaded = draft.FotoKedatanganUploaded,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = fileUrls,
                    FotoPetugasUploaded = true,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileNames, fileUrls, message = $"{fileNames.Count} foto petugas berhasil diupload." });
        }

        [HttpPost("upload-foto-kedatangan")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoKedatangan(
            [FromForm] List<IFormFile>? FotoKedatangan,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] string? WaktuKedatangan,
            [FromForm] string? Latitude,
            [FromForm] string? Longitude,
            [FromForm] string? AlamatJalan)
        {
            if (FotoKedatangan == null || FotoKedatangan.Count == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var fileNames = new List<string>();
            foreach (var file in FotoKedatangan)
            {
                if (file.Length == 0) continue;
                var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
                var name = $"kedatangan_{Guid.NewGuid()}{ext}";
                var path = Path.Combine(uploadDir, name);
                await using var stream = new FileStream(path, FileMode.Create);
                await file.CopyToAsync(stream);
                fileNames.Add(name);
            }
            var fileUrls = fileNames.Select(n => BuildUploadUrl(dateFolder, n)).ToList();

            var resolvedDraftKeyTps = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKeyTps))
            {
                var loadResult = await _detailService.LoadDraftTpsAsync(resolvedDraftKeyTps);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKeyTps, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                draft.FotoKedatanganFileNames = fileUrls;
                draft.FotoKedatanganUploaded = true;
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                if (!string.IsNullOrWhiteSpace(WaktuKedatangan)) draft.WaktuKedatangan = WaktuKedatangan;
                if (!string.IsNullOrWhiteSpace(Latitude)) draft.Latitude = Latitude;
                if (!string.IsNullOrWhiteSpace(Longitude)) draft.Longitude = Longitude;
                if (!string.IsNullOrWhiteSpace(AlamatJalan)) draft.AlamatJalan = AlamatJalan;
                await _detailService.SaveDraftTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKeyTps,
                    SessionKey = resolvedDraftKeyTps,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = fileUrls,
                    FotoKedatanganUploaded = true,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = draft.FotoPetugasFileNames,
                    FotoPetugasUploaded = draft.FotoPetugasUploaded,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileNames, fileUrls, message = $"{fileNames.Count} foto kedatangan berhasil diupload." });
        }

        [HttpPost("upload-foto-timbangan")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoTimbangan(
            [FromForm] IFormFile? FotoTimbangan,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] int ItemIndex,
            [FromForm] string? JenisSampah,
            [FromForm] decimal Berat)
        {
            if (FotoTimbangan == null || FotoTimbangan.Length == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var ext = Path.GetExtension(FotoTimbangan.FileName).ToLowerInvariant();
            var jenisSafe = (JenisSampah ?? "residu").ToLowerInvariant();
            var beratStr = Berat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture).Replace('.', '_');
            var name = $"timbangan{ItemIndex + 1}-{jenisSafe}-{beratStr}{ext}";
            var filePath = Path.Combine(uploadDir, name);
            await using var stream = new FileStream(filePath, FileMode.Create);
            await FotoTimbangan.CopyToAsync(stream);
            var fileUrl = BuildUploadUrl(dateFolder, name);

            var resolvedDraftKeyTps = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKeyTps))
            {
                var loadResult = await _detailService.LoadDraftTpsAsync(resolvedDraftKeyTps);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKeyTps, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                while (draft.Timbangan.Count <= ItemIndex)
                    draft.Timbangan.Add(new DraftTimbanganItem());
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                draft.Timbangan[ItemIndex] = new DraftTimbanganItem
                {
                    FotoFileName = fileUrl,
                    JenisSampah = JenisSampah ?? "Residu",
                    Berat = Berat,
                    Uploaded = true
                };
                await _detailService.SaveDraftTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKeyTps,
                    SessionKey = resolvedDraftKeyTps,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = draft.FotoKedatanganFileNames,
                    FotoKedatanganUploaded = draft.FotoKedatanganUploaded,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = draft.FotoPetugasFileNames,
                    FotoPetugasUploaded = draft.FotoPetugasUploaded,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileName = name, fileUrl, message = $"Foto timbangan #{ItemIndex + 1} berhasil diupload." });
        }

        [HttpPost("upload-foto-petugas")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> UploadFotoPetugas(
            [FromForm] List<IFormFile>? FotoPetugas,
            [FromForm] string? DraftKey,
            [FromForm] string? SessionKey,
            [FromForm] string? SpjDetailId,
            [FromForm] string? LokasiAngkutId,
            [FromForm] string? NamaPetugas)
        {
            if (FotoPetugas == null || FotoPetugas.Count == 0)
                return BadRequest(new { success = false, message = "Tidak ada foto." });

            var dateFolder = DateTime.Now.ToString("yyyy-MM-dd");
            var uploadDir = GetUploadDirectory(dateFolder);

            var fileNames = new List<string>();
            foreach (var file in FotoPetugas)
            {
                if (file.Length == 0) continue;
                var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
                var name = $"petugas_{Guid.NewGuid()}{ext}";
                var path = Path.Combine(uploadDir, name);
                await using var stream = new FileStream(path, FileMode.Create);
                await file.CopyToAsync(stream);
                fileNames.Add(name);
            }
            var fileUrls = fileNames.Select(n => BuildUploadUrl(dateFolder, n)).ToList();

            var resolvedDraftKeyTps = ResolveDraftKey(DraftKey, SessionKey, SpjDetailId, LokasiAngkutId);
            if (!string.IsNullOrWhiteSpace(resolvedDraftKeyTps))
            {
                var loadResult = await _detailService.LoadDraftTpsAsync(resolvedDraftKeyTps);
                var draft = loadResult.Draft ?? new DraftPenjemputanNonTps { SessionKey = resolvedDraftKeyTps, SpjDetailId = SpjDetailId ?? string.Empty, LokasiAngkutId = LokasiAngkutId ?? string.Empty };
                draft.FotoPetugasFileNames = fileUrls;
                draft.FotoPetugasUploaded = true;
                if (!string.IsNullOrWhiteSpace(SpjDetailId)) draft.SpjDetailId = SpjDetailId;
                if (!string.IsNullOrWhiteSpace(LokasiAngkutId)) draft.LokasiAngkutId = LokasiAngkutId;
                if (!string.IsNullOrWhiteSpace(NamaPetugas)) draft.NamaPetugas = NamaPetugas;
                await _detailService.SaveDraftTpsAsync(new DraftSaveRequest
                {
                    DraftKey = resolvedDraftKeyTps,
                    SessionKey = resolvedDraftKeyTps,
                    LokasiAngkutId = draft.LokasiAngkutId,
                    SpjDetailId = draft.SpjDetailId,
                    Latitude = draft.Latitude,
                    Longitude = draft.Longitude,
                    AlamatJalan = draft.AlamatJalan,
                    WaktuKedatangan = draft.WaktuKedatangan,
                    FotoKedatanganFileNames = draft.FotoKedatanganFileNames,
                    FotoKedatanganUploaded = draft.FotoKedatanganUploaded,
                    Timbangan = draft.Timbangan,
                    TotalOrganik = draft.TotalOrganik,
                    TotalAnorganik = draft.TotalAnorganik,
                    TotalResidu = draft.TotalResidu,
                    TotalTimbangan = draft.TotalTimbangan,
                    FotoPetugasFileNames = fileUrls,
                    FotoPetugasUploaded = true,
                    NamaPetugas = draft.NamaPetugas
                });
            }

            return Ok(new { success = true, fileNames, fileUrls, message = $"{fileNames.Count} foto petugas berhasil diupload." });
        }


        [HttpPost("ocr-timbangan")]
        [IgnoreAntiforgeryToken]
        public async Task<IActionResult> OcrTimbangan(IFormFile? Foto)
        {
            if (Foto == null || Foto.Length == 0)
            {
                return BadRequest(new { success = false, message = "Foto tidak ditemukan." });
            }

            if (Foto.Length > 5 * 1024 * 1024)
            {
                return BadRequest(new { success = false, message = "Ukuran foto terlalu besar. Maksimal 5MB." });
            }

            var apiKey = _configuration["OpenRouter:OCRkey"];
            if (string.IsNullOrWhiteSpace(apiKey))
            {
                return StatusCode(500, new { success = false, message = "OpenRouter API key belum diset." });
            }

            byte[] fileBytes;
            await using (var ms = new MemoryStream())
            {
                await Foto.CopyToAsync(ms);
                fileBytes = ms.ToArray();
            }

            var mimeType = string.IsNullOrWhiteSpace(Foto.ContentType) ? "image/jpeg" : Foto.ContentType;
            var base64 = Convert.ToBase64String(fileBytes);
            var dataUrl = $"data:{mimeType};base64,{base64}";

            var payload = new
            {
                // model = "nvidia/nemotron-nano-12b-v2-vl:free",
                model = "google/gemini-2.5-flash-image",
                // model = "google/gemini-2.5-flash-lite",
                // model = "google/gemini-2.5-flash-lite-preview-09-2025",
                temperature = 0,
                messages = new object[]
                {
                    new
                    {
                        role = "user",
                        content = new object[]
                        {
                            new
                            {
                                type = "text",
                                text = @"
                                Baca angka berat timbangan digital pada foto.

                                Rules:
                                - Abaikan tulisan seperti ZERO, TARE, STABLE, AC, PACK, PCS, KG, ADD, HOLD.
                                - Jawab hanya angka dengan format 2 digit desimal pakai titik (contoh: 54.45).
                                - Jika tidak terbaca jawab: UNREADABLE
                                - Fokus pada angka layar LED merah yang menyala.

                                Saya berikan 3 contoh foto timbangan yang benar:
                                Foto 1 = 75.23
                                Foto 2 = 79.86
                                Foto 3 = 54.45

                                Sekarang baca angka pada foto terakhir."
                            },

                            new
                            {
                                type = "image_url",
                                image_url = new { url = "https://res.cloudinary.com/drejcprhe/image/upload/v1770888384/Notes_-_2026-02-11_08.52.31_wonhbm.jpg" }
                            },

                            new
                            {
                                type = "image_url",
                                image_url = new { url = "https://res.cloudinary.com/drejcprhe/image/upload/v1770888429/Notes_-_2026-02-11_08.52.34_xairzy.jpg" }
                            },

                            new
                            {
                                type = "image_url",
                                image_url = new { url = "https://res.cloudinary.com/drejcprhe/image/upload/v1770888473/ChatGPT_Image_Feb_11_2026_03_00_33_PM_ujhdlw.png" }
                            },

                            new
                            {
                                type = "image_url",
                                image_url = new { url = dataUrl }
                            }
                        }
                    }
                }
            };

            var json = JsonSerializer.Serialize(payload);

            var request = new HttpRequestMessage(HttpMethod.Post, "https://openrouter.ai/api/v1/chat/completions");
            request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {apiKey}");
            request.Headers.TryAddWithoutValidation("Accept", "application/json");
            request.Headers.TryAddWithoutValidation("HTTP-Referer", "https://yourdomain.com");
            request.Headers.TryAddWithoutValidation("X-Title", "eSPJ OCR Timbangan");

            request.Content = new StringContent(json, Encoding.UTF8, "application/json");

            var client = _httpClientFactory.CreateClient();
            using var response = await client.SendAsync(request);
            var responseText = await response.Content.ReadAsStringAsync();

            if (!response.IsSuccessStatusCode)
            {
                return StatusCode((int)response.StatusCode, new
                {
                    success = false,
                    message = "OpenRouter request gagal.",
                    detail = responseText
                });
            }

            using var doc = JsonDocument.Parse(responseText);

            var content = doc.RootElement
                .GetProperty("choices")[0]
                .GetProperty("message")
                .GetProperty("content")
                .GetString() ?? "";

            content = content.Trim();

            if (content.Contains("UNREADABLE", StringComparison.OrdinalIgnoreCase))
            {
                return Ok(new
                {
                    success = false,
                    message = "Angka tidak terbaca.",
                    raw = content
                });
            }

            // cari format angka 2 desimal
            var match = Regex.Match(content, @"-?\d{1,5}([.,]\d{2})");

            if (!match.Success)
            {
                return Ok(new
                {
                    success = false,
                    message = "AI tidak menemukan angka valid.",
                    raw = content
                });
            }

            var normalized = match.Value.Replace(',', '.');

            if (!decimal.TryParse(normalized, NumberStyles.Any, CultureInfo.InvariantCulture, out var weight))
            {
                return Ok(new
                {
                    success = false,
                    message = "Format angka AI tidak valid.",
                    raw = content
                });
            }

            return Ok(new
            {
                success = true,
                weight = weight.ToString("0.00", CultureInfo.InvariantCulture),
                raw = content
            });
        }

    }
}
