package state

import (
	"fmt"
	"os"
	"slices"

	"github.com/voocel/ainovel-cli/domain"
)

// LoadProgress 读取 meta/progress.json。不存在时返回 nil。
func (s *Store) LoadProgress() (*domain.Progress, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.loadProgressUnlocked()
}

func (s *Store) loadProgressUnlocked() (*domain.Progress, error) {
	var p domain.Progress
	if err := s.readJSONUnlocked("meta/progress.json", &p); err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		return nil, err
	}
	return &p, nil
}

// SaveProgress 保存进度到 meta/progress.json。
func (s *Store) SaveProgress(p *domain.Progress) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.saveProgressUnlocked(p)
}

func (s *Store) saveProgressUnlocked(p *domain.Progress) error {
	return s.writeJSONUnlocked("meta/progress.json", p)
}

// InitProgress 创建初始进度。
func (s *Store) InitProgress(novelName string, totalChapters int) error {
	return s.SaveProgress(&domain.Progress{
		NovelName:     novelName,
		Phase:         domain.PhaseInit,
		TotalChapters: totalChapters,
	})
}

// SetTotalChapters 根据大纲长度设定总章节数。
func (s *Store) SetTotalChapters(n int) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			p = &domain.Progress{}
		}
		p.TotalChapters = n
		return s.saveProgressUnlocked(p)
	})
}

// UpdatePhase 更新创作阶段。
func (s *Store) UpdatePhase(phase domain.Phase) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			p = &domain.Progress{}
		}
		p.Phase = phase
		return s.saveProgressUnlocked(p)
	})
}

// MarkChapterComplete 标记章节完成，原子性更新进度。
// 支持重写场景：如果章节已完成，先减去旧字数再加新字数。
// hookType 和 dominantStrand 用于节奏追踪，可为空。
func (s *Store) MarkChapterComplete(chapter, wordCount int, hookType, dominantStrand string) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return fmt.Errorf("progress not initialized, call InitProgress first")
		}
		if p.ChapterWordCounts == nil {
			p.ChapterWordCounts = make(map[int]int)
		}
		// 重写场景：减去旧字数
		if oldWC, ok := p.ChapterWordCounts[chapter]; ok {
			p.TotalWordCount -= oldWC
		}
		p.ChapterWordCounts[chapter] = wordCount
		p.TotalWordCount += wordCount
		if !slices.Contains(p.CompletedChapters, chapter) {
			p.CompletedChapters = append(p.CompletedChapters, chapter)
		}
		// 仅在正常推进时更新 CurrentChapter，重写旧章节不回退指针
		if chapter+1 > p.CurrentChapter {
			p.CurrentChapter = chapter + 1
		}
		p.InProgressChapter = 0
		p.CompletedScenes = nil
		p.Phase = domain.PhaseWriting

		// 节奏追踪：按章节顺序填充 history（确保索引对齐）
		if dominantStrand != "" {
			for len(p.StrandHistory) < chapter-1 {
				p.StrandHistory = append(p.StrandHistory, "")
			}
			if len(p.StrandHistory) < chapter {
				p.StrandHistory = append(p.StrandHistory, dominantStrand)
			} else {
				p.StrandHistory[chapter-1] = dominantStrand
			}
		}
		if hookType != "" {
			for len(p.HookHistory) < chapter-1 {
				p.HookHistory = append(p.HookHistory, "")
			}
			if len(p.HookHistory) < chapter {
				p.HookHistory = append(p.HookHistory, hookType)
			} else {
				p.HookHistory[chapter-1] = hookType
			}
		}

		return s.saveProgressUnlocked(p)
	})
}

// MarkComplete 标记全书创作完成。
func (s *Store) MarkComplete() error {
	return s.UpdatePhase(domain.PhaseComplete)
}

// SaveLastCommit 保存最近一次 commit 结果到 meta/last_commit.json。
// 用于宿主程序读取结构化信号。
func (s *Store) SaveLastCommit(result domain.CommitResult) error {
	return s.writeJSON("meta/last_commit.json", result)
}

// LoadLastCommit 读取最近一次 commit 结果。
func (s *Store) LoadLastCommit() (*domain.CommitResult, error) {
	var r domain.CommitResult
	if err := s.readJSON("meta/last_commit.json", &r); err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		return nil, err
	}
	return &r, nil
}

// ClearInProgress 清除进度中间状态（章节提交后调用）。
func (s *Store) ClearInProgress() error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.InProgressChapter = 0
		p.CompletedScenes = nil
		return s.saveProgressUnlocked(p)
	})
}

// ClearLastCommit 清除 commit 信号文件，防止重复消费。
func (s *Store) ClearLastCommit() error {
	return s.removeFile("meta/last_commit.json")
}

// UpdateVolumeArc 更新当前卷弧位置。
func (s *Store) UpdateVolumeArc(volume, arc int) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.CurrentVolume = volume
		p.CurrentArc = arc
		return s.saveProgressUnlocked(p)
	})
}

// SetLayered 设置分层模式标志。
func (s *Store) SetLayered(layered bool) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.Layered = layered
		return s.saveProgressUnlocked(p)
	})
}

// SetFlow 更新当前流程状态。
func (s *Store) SetFlow(flow domain.FlowState) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.Flow = flow
		return s.saveProgressUnlocked(p)
	})
}

// SetPendingRewrites 设置待重写章节队列和原因。
func (s *Store) SetPendingRewrites(chapters []int, reason string) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.PendingRewrites = chapters
		p.RewriteReason = reason
		return s.saveProgressUnlocked(p)
	})
}

// CompleteRewrite 从待重写队列中移除已完成的章节。
// 队列清空时自动将 Flow 重置为 writing 并清除 RewriteReason。
func (s *Store) CompleteRewrite(chapter int) error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		var remaining []int
		for _, ch := range p.PendingRewrites {
			if ch != chapter {
				remaining = append(remaining, ch)
			}
		}
		p.PendingRewrites = remaining
		if len(remaining) == 0 {
			p.Flow = domain.FlowWriting
			p.RewriteReason = ""
		}
		return s.saveProgressUnlocked(p)
	})
}

// ClearPendingRewrites 强制清空重写队列。
func (s *Store) ClearPendingRewrites() error {
	return s.withWriteLock(func() error {
		p, err := s.loadProgressUnlocked()
		if err != nil {
			return err
		}
		if p == nil {
			return nil
		}
		p.PendingRewrites = nil
		p.RewriteReason = ""
		p.Flow = domain.FlowWriting
		return s.saveProgressUnlocked(p)
	})
}

// ValidateChapterCommit 校验当前章节是否允许提交。
// 在重写/打磨流程中，只允许提交待处理队列中的章节。
func (s *Store) ValidateChapterCommit(chapter int) error {
	p, err := s.LoadProgress()
	if err != nil {
		return err
	}
	if p == nil {
		return nil
	}
	if p.Flow != domain.FlowRewriting && p.Flow != domain.FlowPolishing {
		return nil
	}
	if slices.Contains(p.PendingRewrites, chapter) {
		return nil
	}

	verb := "重写"
	if p.Flow == domain.FlowPolishing {
		verb = "打磨"
	}
	return fmt.Errorf("第 %d 章不在待%s队列中，当前队列：%v", chapter, verb, p.PendingRewrites)
}
