using System.Text.Json;
using eSPJ.Models;

namespace eSPJ.Services
{
    public class DetailPenjemputanService
    {
        private readonly string _dataFilePath;
        private readonly IWebHostEnvironment _env;
        private readonly ILogger<DetailPenjemputanService> _logger;

        public DetailPenjemputanService(
            IWebHostEnvironment env,
            ILogger<DetailPenjemputanService> logger)
        {
            _env = env;
            _logger = logger;
            _dataFilePath = Path.Combine(_env.ContentRootPath, "Data", "detail-penjemputan.json");
        }

        public async Task<List<TpsData>> GetAllTpsDataAsync()
        {
            try
            {
                if (!File.Exists(_dataFilePath))
                {
                    return new List<TpsData>();
                }

                var json = await File.ReadAllTextAsync(_dataFilePath);
                var data = JsonSerializer.Deserialize<List<TpsData>>(json);
                return data ?? new List<TpsData>();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error reading TPS data from JSON");
                return new List<TpsData>();
            }
        }

        public async Task<bool> SaveTpsDataAsync(List<TpsData> data)
        {
            try
            {
                var directory = Path.GetDirectoryName(_dataFilePath);
                if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var options = new JsonSerializerOptions
                {
                    WriteIndented = true
                };

                var json = JsonSerializer.Serialize(data, options);
                await File.WriteAllTextAsync(_dataFilePath, json);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error saving TPS data to JSON");
                return false;
            }
        }

        public async Task<DetailPenjemputanResponse> SubmitPenjemputanAsync(DetailPenjemputanRequest request)
        {
            try
            {
                // Validate request
                if (string.IsNullOrEmpty(request.TpsName))
                {
                    return new DetailPenjemputanResponse
                    {
                        Success = false,
                        Message = "Nama TPS harus diisi"
                    };
                }

                if (request.FotoKedatangan == null || !request.FotoKedatangan.Any())
                {
                    return new DetailPenjemputanResponse
                    {
                        Success = false,
                        Message = "Foto kedatangan harus diupload"
                    };
                }

                if (request.FotoTimbangan == null || !request.FotoTimbangan.Any())
                {
                    return new DetailPenjemputanResponse
                    {
                        Success = false,
                        Message = "Foto timbangan harus diupload"
                    };
                }

                if (request.FotoPetugas == null || !request.FotoPetugas.Any())
                {
                    return new DetailPenjemputanResponse
                    {
                        Success = false,
                        Message = "Foto petugas harus diupload"
                    };
                }

                if (string.IsNullOrEmpty(request.NamaPetugas))
                {
                    return new DetailPenjemputanResponse
                    {
                        Success = false,
                        Message = "Nama petugas harus diisi"
                    };
                }

                var uploadPath = Path.Combine(_env.ContentRootPath, "uploads", "penjemputan", DateTime.Now.ToString("yyyy-MM-dd"));
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                var tpsData = new TpsData
                {
                    Name = request.TpsName,
                    Latitude = request.Latitude,
                    Longitude = request.Longitude,
                    AlamatJalan = request.AlamatJalan,
                    WaktuKedatangan = request.WaktuKedatangan,
                    TotalTimbangan = request.TotalTimbangan,
                    TotalOrganik = request.TotalOrganik,
                    TotalAnorganik = request.TotalAnorganik,
                    TotalResidu = request.TotalResidu,
                    NamaPetugas = request.NamaPetugas,
                    Submitted = true,
                    FotoKedatanganUploaded = true,
                    FotoPetugasUploaded = true
                };

                // Save foto kedatangan
                foreach (var file in request.FotoKedatangan)
                {
                    var fileName = $"kedatangan_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
                    var filePath = Path.Combine(uploadPath, fileName);
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }
                    tpsData.FotoKedatangan.Add($"{uploadBaseUrl}/{fileName}");
                }

                // Save foto timbangan
                if (request.BeratTimbangan != null && request.JenisSampahList != null)
                {
                    for (int i = 0; i < request.FotoTimbangan.Count; i++)
                    {
                        var file = request.FotoTimbangan[i];
                        var fileName = $"timbangan_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
                        var filePath = Path.Combine(uploadPath, fileName);
                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            await file.CopyToAsync(stream);
                        }

                        var jenisSampah = JenisSampah.Residu;
                        if (i < request.JenisSampahList.Count && Enum.TryParse<JenisSampah>(request.JenisSampahList[i], out var parsed))
                        {
                            jenisSampah = parsed;
                        }

                        tpsData.Timbangan.Add(new TimbanganItem
                        {
                            FotoFileName = $"{uploadBaseUrl}/{fileName}",
                            Berat = new List<decimal> { (i < request.BeratTimbangan.Count ? request.BeratTimbangan[i] : 0) },
                            LokasiAngkut = new List<string>(),
                            JenisSampah = new List<JenisSampah> { jenisSampah },
                            IsUploaded = true,
                            WaktuUpload = DateTime.Now
                        });
                    }
                }

                // Save foto petugas
                foreach (var file in request.FotoPetugas)
                {
                    var fileName = $"petugas_{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
                    var filePath = Path.Combine(uploadPath, fileName);
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }
                    tpsData.FotoPetugas.Add($"{uploadBaseUrl}/{fileName}");
                }

                var allData = await GetAllTpsDataAsync();
                allData.Add(tpsData);
                await SaveTpsDataAsync(allData);

                return new DetailPenjemputanResponse
                {
                    Success = true,
                    Message = "Data penjemputan berhasil disimpan",
                    Data = tpsData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error submitting penjemputan data");
                return new DetailPenjemputanResponse
                {
                    Success = false,
                    Message = $"Terjadi kesalahan: {ex.Message}"
                };
            }
        }

        private string GetDraftFilePath(string prefix, string sessionKey)
        {
            var dir = Path.Combine(_env.ContentRootPath, "Data", "drafts");
            if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
            var safe = string.Concat(sessionKey.Where(c => char.IsLetterOrDigit(c) || c == '-' || c == '_'));
            if (string.IsNullOrEmpty(safe)) safe = "default";
            return Path.Combine(dir, $"draft-{prefix}-{safe}.json");
        }

        private Task<DraftSaveResponse> SaveDraftAsync(string prefix, DraftSaveRequest request)
        {
            return SaveDraftInternalAsync(prefix, request);
        }

        private async Task<DraftSaveResponse> SaveDraftInternalAsync(string prefix, DraftSaveRequest request)
        {
            try
            {
                var filePath = GetDraftFilePath(prefix, request.SessionKey);
                var draft = new DraftPenjemputanNonTps
                {
                    SessionKey = request.SessionKey,
                    LokasiAngkutId = request.LokasiAngkutId,
                    SpjDetailId = request.SpjDetailId,
                    Latitude = request.Latitude,
                    Longitude = request.Longitude,
                    AlamatJalan = request.AlamatJalan,
                    WaktuKedatangan = request.WaktuKedatangan,
                    FotoKedatanganFileNames = request.FotoKedatanganFileNames,
                    FotoKedatanganUploaded = request.FotoKedatanganUploaded,
                    Timbangan = request.Timbangan,
                    TotalOrganik = request.TotalOrganik,
                    TotalAnorganik = request.TotalAnorganik,
                    TotalResidu = request.TotalResidu,
                    TotalTimbangan = request.TotalTimbangan,
                    FotoPetugasFileNames = request.FotoPetugasFileNames,
                    FotoPetugasUploaded = request.FotoPetugasUploaded,
                    NamaPetugas = request.NamaPetugas,
                    UpdatedAt = DateTime.Now
                };

                var options = new JsonSerializerOptions { WriteIndented = true };
                var json = JsonSerializer.Serialize(draft, options);
                await File.WriteAllTextAsync(filePath, json);

                return new DraftSaveResponse { Success = true, Message = "Draft tersimpan.", DraftKey = request.DraftKey, SessionKey = request.SessionKey };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error saving {Prefix} draft", prefix);
                return new DraftSaveResponse { Success = false, Message = $"Gagal menyimpan draft: {ex.Message}" };
            }
        }

        public async Task<DraftSaveResponse> SaveDraftNonTpsAsync(DraftSaveRequest request)
        {
            return await SaveDraftAsync("non-tps", request);
        }

        public async Task<DraftSaveResponse> SaveDraftTpsAsync(DraftSaveRequest request)
        {
            return await SaveDraftAsync("tps", request);
        }

        public async Task<DraftLoadResponse> LoadDraftNonTpsAsync(string sessionKey)
        {
            return await LoadDraftAsync("non-tps", sessionKey);
        }

        public async Task<DraftLoadResponse> LoadDraftTpsAsync(string sessionKey)
        {
            return await LoadDraftAsync("tps", sessionKey);
        }

        private async Task<DraftLoadResponse> LoadDraftAsync(string prefix, string sessionKey)
        {
            try
            {
                var filePath = GetDraftFilePath(prefix, sessionKey);
                if (!File.Exists(filePath))
                    return new DraftLoadResponse { Success = true, HasDraft = false, Message = "Tidak ada draft." };

                var json = await File.ReadAllTextAsync(filePath);
                var draft = JsonSerializer.Deserialize<DraftPenjemputanNonTps>(json,
                    new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

                if (draft == null)
                    return new DraftLoadResponse { Success = true, HasDraft = false, Message = "Draft kosong." };

                return new DraftLoadResponse { Success = true, HasDraft = true, Draft = draft };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error loading {Prefix} draft", prefix);
                return new DraftLoadResponse { Success = false, HasDraft = false, Message = $"Gagal memuat draft: {ex.Message}" };
            }
        }

        public async Task<bool> DeleteDraftNonTpsAsync(string sessionKey)
        {
            return await DeleteDraftAsync("non-tps", sessionKey);
        }

        public async Task<bool> DeleteDraftTpsAsync(string sessionKey)
        {
            return await DeleteDraftAsync("tps", sessionKey);
        }

        private async Task<bool> DeleteDraftAsync(string prefix, string sessionKey)
        {
            try
            {
                var filePath = GetDraftFilePath(prefix, sessionKey);
                if (File.Exists(filePath)) File.Delete(filePath);
                await Task.CompletedTask;
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting {Prefix} draft", prefix);
                return false;
            }
        }

        public async Task<OcrTimbanganResponse> ProcessOcrTimbanganAsync(IFormFile foto)
        {
            try
            {
                await Task.Delay(500);

                return new OcrTimbanganResponse
                {
                    Success = true,
                    Weight = "54.50",
                    Raw = "54.50 kg",
                    Message = "OCR processed successfully (mock)"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing OCR timbangan");
                return new OcrTimbanganResponse
                {
                    Success = false,
                    Message = $"Terjadi kesalahan: {ex.Message}"
                };
            }
        }
    }
}
