package services

import (
	"os"
	"path/filepath"
	"testing"
)

func TestParseCalibreMetadataOPF(t *testing.T) {
	tests := []struct {
		name       string
		opfContent string
		wantTitle  string
		wantAuthor string
		wantSeries string
		wantTags   int
		wantErr    bool
	}{
		{
			name: "Complete metadata.opf",
			opfContent: `<?xml version='1.0' encoding='utf-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:title>Test Book</dc:title>
    <dc:creator>Test Author</dc:creator>
    <dc:subject>Fantasy</dc:subject>
    <dc:subject>Adventure</dc:subject>
    <dc:description>Test description</dc:description>
    <dc:publisher>Test Publisher</dc:publisher>
    <dc:date>2024-01-15</dc:date>
    <dc:language>en</dc:language>
    <dc:identifier opf:scheme="ISBN">978-0-123456-78-9</dc:identifier>
    <dc:contributor>Contributor Name</dc:contributor>
    <meta name="calibre:series" content="Test Series"/>
    <meta name="calibre:series_index" content="1"/>
  </metadata>
</package>`,
			wantTitle:  "Test Book",
			wantAuthor: "Test Author",
			wantSeries: "Test Series",
			wantTags:   2,
			wantErr:    false,
		},
		{
			name: "Minimal metadata.opf",
			opfContent: `<?xml version='1.0' encoding='utf-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:title>Minimal Book</dc:title>
  </metadata>
</package>`,
			wantTitle:  "Minimal Book",
			wantAuthor: "",
			wantSeries: "",
			wantTags:   0,
			wantErr:    false,
		},
		{
			name: "Malformed XML",
			opfContent: `<?xml version='1.0' encoding='utf-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:title>Test`,
			wantTitle:  "",
			wantAuthor: "",
			wantSeries: "",
			wantTags:   0,
			wantErr:    true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create temporary OPF file
			tmpDir := t.TempDir()
			opfPath := filepath.Join(tmpDir, "metadata.opf")
			if err := os.WriteFile(opfPath, []byte(tt.opfContent), 0644); err != nil {
				t.Fatalf("Failed to create test OPF: %v", err)
			}

			// Parse
			scanner := &MediaScanner{}
			got, err := scanner.parseCalibreMetadataOPF(opfPath)

			if (err != nil) != tt.wantErr {
				t.Errorf("parseCalibreMetadataOPF() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if !tt.wantErr && got.Title != tt.wantTitle {
				t.Errorf("Title = %v, want %v", got.Title, tt.wantTitle)
			}
			if !tt.wantErr && got.Author != tt.wantAuthor {
				t.Errorf("Author = %v, want %v", got.Author, tt.wantAuthor)
			}
			if !tt.wantErr && got.Series != tt.wantSeries {
				t.Errorf("Series = %v, want %v", got.Series, tt.wantSeries)
			}
			if !tt.wantErr && len(got.Tags) != tt.wantTags {
				t.Errorf("Tags length = %v, want %v", len(got.Tags), tt.wantTags)
			}
		})
	}
}

func TestExtractCalibreSidecar(t *testing.T) {
	t.Run("Sidecar exists", func(t *testing.T) {
		tmpDir := t.TempDir()
		opfPath := filepath.Join(tmpDir, "metadata.opf")
		bookPath := filepath.Join(tmpDir, "book.epub")

		// Create OPF file
		opfContent := `<?xml version='1.0' encoding='utf-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:title>Sidecar Test</dc:title>
    <dc:creator>Test Author</dc:creator>
  </metadata>
</package>`
		if err := os.WriteFile(opfPath, []byte(opfContent), 0644); err != nil {
			t.Fatal(err)
		}

		// Test extraction
		scanner := &MediaScanner{}
		metadata := scanner.extractCalibreSidecar(bookPath)

		if metadata == nil {
			t.Error("Expected metadata, got nil")
			return
		}

		if metadata.Title != "Sidecar Test" {
			t.Errorf("Title = %v, want 'Sidecar Test'", metadata.Title)
		}
	})

	t.Run("No sidecar", func(t *testing.T) {
		tmpDir := t.TempDir()
		bookPath := filepath.Join(tmpDir, "book.epub")

		scanner := &MediaScanner{}
		metadata := scanner.extractCalibreSidecar(bookPath)

		if metadata != nil {
			t.Error("Expected nil, got metadata")
		}
	})
}
