package pocketbase

import (
	"encoding/json"

	"clio/internal/link"
	"clio/internal/processor"

	"github.com/pocketbase/pocketbase/core"
	"github.com/pocketbase/pocketbase/tools/types"
)

// Store implements processor.Store for Link using PocketBase.
type Store struct {
	app core.App
}

// New creates a new PocketBase store for links.
func New(app core.App) *Store {
	return &Store{app: app}
}

// Get retrieves a link by ID from PocketBase.
func (s *Store) Get(id string) (processor.Record, error) {
	record, err := s.app.FindRecordById("links", id)
	if err != nil {
		return nil, err
	}

	created := record.GetDateTime("created")
	updated := record.GetDateTime("updated")

	l := &link.Link{
		ID:           record.Id,
		InitialURL:   record.GetString("initial_url"), // ss
		Status:       record.GetString("status"),
		CurrentPhase: stringPtr(record.GetString("current_phase")),
		Created:      created.Time(),
		Updated:      updated.Time(),
	}

	// Unmarshal completed_phases JSON
	if completedPhasesRaw := record.Get("completed_phases"); completedPhasesRaw != nil {
		switch v := completedPhasesRaw.(type) {
		case types.JSONRaw:
			json.Unmarshal(v, &l.CompletedPhases)
		case string:
			if v != "" {
				json.Unmarshal([]byte(v), &l.CompletedPhases)
			}
		}
	}

	// Unmarshal phase_results JSON
	if phaseResultsRaw := record.Get("phase_results"); phaseResultsRaw != nil {
		switch v := phaseResultsRaw.(type) {
		case types.JSONRaw:
			json.Unmarshal(v, &l.PhaseResults)
		case string:
			if v != "" {
				json.Unmarshal([]byte(v), &l.PhaseResults)
			}
		}
	}

	if errorMsg := record.GetString("error_message"); errorMsg != "" {
		l.ErrorMessage = &errorMsg
	}

	return l, nil
}

// Save persists a link to PocketBase.
func (s *Store) Save(record processor.Record) error {
	l, ok := record.(*link.Link)
	if !ok {
		return nil // Type assertion failed, but we'll just return nil to avoid panics in production
	}

	pbRecord, err := s.app.FindRecordById("links", l.ID)
	if err != nil {
		// Create new record
		collection, err := s.app.FindCollectionByNameOrId("links")
		if err != nil {
			return err
		}
		pbRecord = core.NewRecord(collection)
		pbRecord.Set("id", l.ID)
	}

	pbRecord.Set("initial_url", l.InitialURL)
	pbRecord.Set("status", l.Status)
	pbRecord.Set("current_phase", l.CurrentPhase)

	completedPhasesJSON, _ := json.Marshal(l.CompletedPhases)
	pbRecord.Set("completed_phases", string(completedPhasesJSON))

	phaseResultsJSON, _ := json.Marshal(l.PhaseResults)
	pbRecord.Set("phase_results", string(phaseResultsJSON))

	if l.ErrorMessage != nil {
		pbRecord.Set("error_message", *l.ErrorMessage)
	}

	return s.app.Save(pbRecord)
}

// stringPtr returns a pointer to a string, or nil if empty.
func stringPtr(s string) *string {
	if s == "" {
		return nil
	}
	return &s
}
