package services

import (
	"bytes"
	"fmt"
	"time"

	"github.com/go-pdf/fpdf"
)

// PDFService handles PDF generation
type PDFService struct{}

// NewPDFService creates a new PDF service
func NewPDFService() *PDFService {
	return &PDFService{}
}

// GenerateTasksReportPDF generates a PDF report from task report data
func (s *PDFService) GenerateTasksReportPDF(report *TasksReportResponse) ([]byte, error) {
	pdf := fpdf.New("P", "mm", "A4", "")
	pdf.SetMargins(15, 15, 15)
	pdf.AddPage()

	// Translate UTF-8 strings to Windows-1252 for built-in fonts
	tr := pdf.UnicodeTranslatorFromDescriptor("")

	// Header
	pdf.SetFont("Arial", "B", 20)
	pdf.SetTextColor(51, 51, 51)
	pdf.Cell(0, 12, "Tasks Report")
	pdf.Ln(14)

	// Residence name
	pdf.SetFont("Arial", "", 14)
	pdf.SetTextColor(102, 102, 102)
	pdf.Cell(0, 8, tr(report.ResidenceName))
	pdf.Ln(10)

	// Generated date
	pdf.SetFont("Arial", "", 10)
	pdf.Cell(0, 6, fmt.Sprintf("Generated: %s", report.GeneratedAt.Format("January 2, 2006 at 3:04 PM")))
	pdf.Ln(12)

	// Summary section
	pdf.SetFont("Arial", "B", 14)
	pdf.SetTextColor(51, 51, 51)
	pdf.Cell(0, 8, "Summary")
	pdf.Ln(10)

	// Summary box
	pdf.SetFillColor(248, 249, 250)
	pdf.Rect(15, pdf.GetY(), 180, 30, "F")

	y := pdf.GetY() + 5
	pdf.SetXY(20, y)
	pdf.SetFont("Arial", "B", 12)
	pdf.SetTextColor(51, 51, 51)

	// Summary columns
	colWidth := 45.0
	pdf.Cell(colWidth, 6, "Total Tasks")
	pdf.Cell(colWidth, 6, "Completed")
	pdf.Cell(colWidth, 6, "Pending")
	pdf.Cell(colWidth, 6, "Overdue")
	pdf.Ln(8)

	pdf.SetX(20)
	pdf.SetFont("Arial", "", 16)
	pdf.Cell(colWidth, 8, fmt.Sprintf("%d", report.TotalTasks))
	pdf.SetTextColor(40, 167, 69) // Green
	pdf.Cell(colWidth, 8, fmt.Sprintf("%d", report.Completed))
	pdf.SetTextColor(255, 193, 7) // Yellow/Orange
	pdf.Cell(colWidth, 8, fmt.Sprintf("%d", report.Pending))
	pdf.SetTextColor(220, 53, 69) // Red
	pdf.Cell(colWidth, 8, fmt.Sprintf("%d", report.Overdue))

	pdf.Ln(25)

	// Tasks table
	pdf.SetTextColor(51, 51, 51)
	pdf.SetFont("Arial", "B", 14)
	pdf.Cell(0, 8, "Tasks")
	pdf.Ln(10)

	if len(report.Tasks) == 0 {
		pdf.SetFont("Arial", "I", 11)
		pdf.SetTextColor(128, 128, 128)
		pdf.Cell(0, 8, "No tasks found for this residence.")
	} else {
		// Table header
		pdf.SetFont("Arial", "B", 10)
		pdf.SetFillColor(233, 236, 239)
		pdf.SetTextColor(51, 51, 51)

		pdf.CellFormat(70, 8, "Title", "1", 0, "L", true, 0, "")
		pdf.CellFormat(30, 8, "Category", "1", 0, "C", true, 0, "")
		pdf.CellFormat(25, 8, "Priority", "1", 0, "C", true, 0, "")
		pdf.CellFormat(25, 8, "Status", "1", 0, "C", true, 0, "")
		pdf.CellFormat(30, 8, "Due Date", "1", 0, "C", true, 0, "")
		pdf.Ln(-1)

		// Table rows
		pdf.SetFont("Arial", "", 9)
		for _, task := range report.Tasks {
			// Check if we need a new page
			if pdf.GetY() > 270 {
				pdf.AddPage()
				// Repeat header
				pdf.SetFont("Arial", "B", 10)
				pdf.SetFillColor(233, 236, 239)
				pdf.CellFormat(70, 8, "Title", "1", 0, "L", true, 0, "")
				pdf.CellFormat(30, 8, "Category", "1", 0, "C", true, 0, "")
				pdf.CellFormat(25, 8, "Priority", "1", 0, "C", true, 0, "")
				pdf.CellFormat(25, 8, "Status", "1", 0, "C", true, 0, "")
				pdf.CellFormat(30, 8, "Due Date", "1", 0, "C", true, 0, "")
				pdf.Ln(-1)
				pdf.SetFont("Arial", "", 9)
			}

			// Determine row color based on status
			if task.IsCancelled {
				pdf.SetFillColor(248, 215, 218) // Light red
			} else if task.IsCompleted {
				pdf.SetFillColor(212, 237, 218) // Light green
			} else if task.IsArchived {
				pdf.SetFillColor(226, 227, 229) // Light gray
			} else {
				pdf.SetFillColor(255, 255, 255) // White
			}

			// Title (truncate if too long, use runes to avoid cutting multi-byte UTF-8 characters)
			title := task.Title
			titleRunes := []rune(title)
			if len(titleRunes) > 35 {
				title = string(titleRunes[:32]) + "..."
			}

			// Status text
			var status string
			if task.IsCancelled {
				status = "Cancelled"
			} else if task.IsCompleted {
				status = "Completed"
			} else if task.IsArchived {
				status = "Archived"
			} else {
				status = task.Status
			}

			// Due date
			dueDate := "-"
			if task.DueDate != nil {
				dueDate = task.DueDate.Format("Jan 2, 2006")
			}

			pdf.SetTextColor(51, 51, 51)
			pdf.CellFormat(70, 7, tr(title), "1", 0, "L", true, 0, "")
			pdf.CellFormat(30, 7, tr(task.Category), "1", 0, "C", true, 0, "")
			pdf.CellFormat(25, 7, tr(task.Priority), "1", 0, "C", true, 0, "")
			pdf.CellFormat(25, 7, tr(status), "1", 0, "C", true, 0, "")
			pdf.CellFormat(30, 7, dueDate, "1", 0, "C", true, 0, "")
			pdf.Ln(-1)
		}
	}

	// Footer
	pdf.SetY(-25)
	pdf.SetFont("Arial", "I", 9)
	pdf.SetTextColor(128, 128, 128)
	pdf.Cell(0, 10, tr(fmt.Sprintf("honeyDue - Tasks Report for %s", report.ResidenceName)))
	pdf.Ln(5)
	pdf.Cell(0, 10, fmt.Sprintf("Generated on %s", time.Now().UTC().Format("2006-01-02 15:04:05 UTC")))

	// Output to buffer
	var buf bytes.Buffer
	if err := pdf.Output(&buf); err != nil {
		return nil, fmt.Errorf("failed to generate PDF: %w", err)
	}

	return buf.Bytes(), nil
}
