package ucca

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"gopkg.in/yaml.v3"
)

// DSGVOObligationsConfig is the YAML structure for DSGVO obligations
type DSGVOObligationsConfig struct {
	Regulation        string                 `yaml:"regulation"`
	Name              string                 `yaml:"name"`
	Obligations       []ObligationYAML       `yaml:"obligations"`
	Controls          []ControlYAML          `yaml:"controls"`
	IncidentDeadlines []IncidentDeadlineYAML `yaml:"incident_deadlines"`
}

func (m *DSGVOModule) loadFromYAML() error {
	searchPaths := []string{
		"policies/obligations/dsgvo_obligations.yaml",
		filepath.Join(".", "policies", "obligations", "dsgvo_obligations.yaml"),
		filepath.Join("..", "policies", "obligations", "dsgvo_obligations.yaml"),
		filepath.Join("..", "..", "policies", "obligations", "dsgvo_obligations.yaml"),
		"/app/policies/obligations/dsgvo_obligations.yaml",
	}

	var data []byte
	var err error
	for _, path := range searchPaths {
		data, err = os.ReadFile(path)
		if err == nil {
			break
		}
	}

	if err != nil {
		return fmt.Errorf("DSGVO obligations YAML not found: %w", err)
	}

	var config DSGVOObligationsConfig
	if err := yaml.Unmarshal(data, &config); err != nil {
		return fmt.Errorf("failed to parse DSGVO YAML: %w", err)
	}

	m.convertObligations(config.Obligations)
	m.convertControls(config.Controls)
	m.convertIncidentDeadlines(config.IncidentDeadlines)

	return nil
}

func (m *DSGVOModule) convertObligations(yamlObls []ObligationYAML) {
	for _, y := range yamlObls {
		obl := Obligation{
			ID:              y.ID,
			RegulationID:    "dsgvo",
			Title:           y.Title,
			Description:     y.Description,
			AppliesWhen:     y.AppliesWhen,
			Category:        ObligationCategory(y.Category),
			Responsible:     ResponsibleRole(y.Responsible),
			Priority:        ObligationPriority(y.Priority),
			ISO27001Mapping: y.ISO27001,
			HowToImplement:  y.HowTo,
		}

		for _, lb := range y.LegalBasis {
			obl.LegalBasis = append(obl.LegalBasis, LegalReference{
				Norm:    lb.Norm,
				Article: lb.Article,
			})
		}

		if y.Deadline != nil {
			obl.Deadline = &Deadline{
				Type:     DeadlineType(y.Deadline.Type),
				Duration: y.Deadline.Duration,
			}
			if y.Deadline.Date != "" {
				if t, err := time.Parse("2006-01-02", y.Deadline.Date); err == nil {
					obl.Deadline.Date = &t
				}
			}
		}

		if y.Sanctions != nil {
			obl.Sanctions = &SanctionInfo{
				MaxFine:           y.Sanctions.MaxFine,
				PersonalLiability: y.Sanctions.PersonalLiability,
			}
		}

		for _, e := range y.Evidence {
			obl.Evidence = append(obl.Evidence, EvidenceItem{Name: e, Required: true})
		}

		m.obligations = append(m.obligations, obl)
	}
}

func (m *DSGVOModule) convertControls(yamlCtrls []ControlYAML) {
	for _, y := range yamlCtrls {
		ctrl := ObligationControl{
			ID:              y.ID,
			RegulationID:    "dsgvo",
			Name:            y.Name,
			Description:     y.Description,
			Category:        y.Category,
			WhatToDo:        y.WhatToDo,
			ISO27001Mapping: y.ISO27001,
			Priority:        ObligationPriority(y.Priority),
		}
		m.controls = append(m.controls, ctrl)
	}
}

func (m *DSGVOModule) convertIncidentDeadlines(yamlDeadlines []IncidentDeadlineYAML) {
	for _, y := range yamlDeadlines {
		deadline := IncidentDeadline{
			RegulationID: "dsgvo",
			Phase:        y.Phase,
			Deadline:     y.Deadline,
			Content:      y.Content,
			Recipient:    y.Recipient,
		}
		for _, lb := range y.LegalBasis {
			deadline.LegalBasis = append(deadline.LegalBasis, LegalReference{
				Norm:    lb.Norm,
				Article: lb.Article,
			})
		}
		m.incidentDeadlines = append(m.incidentDeadlines, deadline)
	}
}
