package iace

import (
	"archive/zip"
	"bytes"
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

// ExportDOCX generates a minimal DOCX file containing the CE technical file sections
func (e *DocumentExporter) ExportDOCX(
	project *Project,
	sections []TechFileSection,
) ([]byte, error) {
	if project == nil {
		return nil, fmt.Errorf("project must not be nil")
	}

	var buf bytes.Buffer
	zw := zip.NewWriter(&buf)

	contentTypes := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  <Default Extension="xml" ContentType="application/xml"/>
  <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
</Types>`
	if err := addZipEntry(zw, "[Content_Types].xml", contentTypes); err != nil {
		return nil, fmt.Errorf("failed to write [Content_Types].xml: %w", err)
	}

	rels := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
</Relationships>`
	if err := addZipEntry(zw, "_rels/.rels", rels); err != nil {
		return nil, fmt.Errorf("failed to write _rels/.rels: %w", err)
	}

	docRels := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
</Relationships>`
	if err := addZipEntry(zw, "word/_rels/document.xml.rels", docRels); err != nil {
		return nil, fmt.Errorf("failed to write word/_rels/document.xml.rels: %w", err)
	}

	docXML := e.buildDocumentXML(project, sections)
	if err := addZipEntry(zw, "word/document.xml", docXML); err != nil {
		return nil, fmt.Errorf("failed to write word/document.xml: %w", err)
	}

	if err := zw.Close(); err != nil {
		return nil, fmt.Errorf("failed to close ZIP: %w", err)
	}

	return buf.Bytes(), nil
}

func (e *DocumentExporter) buildDocumentXML(project *Project, sections []TechFileSection) string {
	var body strings.Builder

	body.WriteString(docxHeading(fmt.Sprintf("CE-Akte: %s", project.MachineName), 1))

	metaLines := []string{
		fmt.Sprintf("Hersteller: %s", project.Manufacturer),
		fmt.Sprintf("Maschinentyp: %s", project.MachineType),
	}
	if project.CEMarkingTarget != "" {
		metaLines = append(metaLines, fmt.Sprintf("CE-Kennzeichnungsziel: %s", project.CEMarkingTarget))
	}
	metaLines = append(metaLines,
		fmt.Sprintf("Status: %s", project.Status),
		fmt.Sprintf("Datum: %s", time.Now().Format("02.01.2006")),
	)
	for _, line := range metaLines {
		body.WriteString(docxParagraph(line, false))
	}

	if project.Description != "" {
		body.WriteString(docxParagraph("", false))
		body.WriteString(docxParagraph(project.Description, true))
	}

	for _, section := range sections {
		body.WriteString(docxHeading(section.Title, 2))
		body.WriteString(docxParagraph(
			fmt.Sprintf("Typ: %s | Status: %s | Version: %d",
				section.SectionType, string(section.Status), section.Version),
			true,
		))

		if section.Content != "" {
			for _, line := range strings.Split(section.Content, "\n") {
				body.WriteString(docxParagraph(line, false))
			}
		} else {
			body.WriteString(docxParagraph("(Kein Inhalt vorhanden)", true))
		}
	}

	body.WriteString(docxParagraph("", false))
	body.WriteString(docxParagraph(
		fmt.Sprintf("Generiert am %s mit BreakPilot AI Compliance SDK",
			time.Now().Format("02.01.2006 15:04")),
		true,
	))

	return fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:o="urn:schemas-microsoft-com:office:office"
            xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
            xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
            xmlns:v="urn:schemas-microsoft-com:vml"
            xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
            xmlns:w10="urn:schemas-microsoft-com:office:word"
            xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
            xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
            xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
            xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
            xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
            xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"
            mc:Ignorable="w14 wp14">
  <w:body>
%s
  </w:body>
</w:document>`, body.String())
}

// ExportJSON returns a JSON representation of the project export data
func (e *DocumentExporter) ExportJSON(
	project *Project,
	sections []TechFileSection,
	hazards []Hazard,
	assessments []RiskAssessment,
	mitigations []Mitigation,
	classifications []RegulatoryClassification,
) ([]byte, error) {
	if project == nil {
		return nil, fmt.Errorf("project must not be nil")
	}

	payload := map[string]interface{}{
		"project":         project,
		"sections":        sections,
		"hazards":         hazards,
		"assessments":     assessments,
		"mitigations":     mitigations,
		"classifications": classifications,
		"exported_at":     time.Now().UTC().Format(time.RFC3339),
		"format_version":  "1.0",
	}

	data, err := json.MarshalIndent(payload, "", "  ")
	if err != nil {
		return nil, fmt.Errorf("failed to marshal JSON: %w", err)
	}
	return data, nil
}
