package service

import (
	"errors"
	"strings"

	"git.iioio.com/freefire/jiang13-forum/model"
)

var (
	ErrSitePageNotFound = errors.New("单页不存在")
	ErrSitePageSlugUsed = errors.New("slug 已被占用")
)

// SitePageService 自定义单页
type SitePageService struct {
	filter *SensitiveFilter
}

func NewSitePageService(filter *SensitiveFilter) *SitePageService {
	return &SitePageService{filter: filter}
}

// SitePageSummary 公开列表摘要
type SitePageSummary struct {
	ID           uint   `json:"id"`
	Title        string `json:"title"`
	Slug         string `json:"slug"`
	ShowInFooter bool   `json:"show_in_footer"`
	ShowInNav    bool   `json:"show_in_nav"`
	SortOrder    int    `json:"sort_order"`
}

func (s *SitePageService) ListPublished() ([]SitePageSummary, error) {
	var rows []model.SitePage
	err := model.DB.Where("published = ?", true).
		Order("sort_order ASC, id ASC").
		Find(&rows).Error
	if err != nil {
		return nil, err
	}
	out := make([]SitePageSummary, len(rows))
	for i, p := range rows {
		out[i] = SitePageSummary{
			ID: p.ID, Title: p.Title, Slug: p.Slug,
			ShowInFooter: p.ShowInFooter, ShowInNav: p.ShowInNav, SortOrder: p.SortOrder,
		}
	}
	return out, nil
}

func (s *SitePageService) ListAll() ([]model.SitePage, error) {
	var rows []model.SitePage
	err := model.DB.Order("sort_order ASC, id ASC").Find(&rows).Error
	if err != nil {
		return nil, err
	}
	return rows, nil
}

func (s *SitePageService) GetBySlug(slug string, allowUnpublished bool) (*model.SitePage, error) {
	slug, ok := NormalizePageSlug(slug)
	if !ok {
		return nil, ErrSitePageNotFound
	}
	var page model.SitePage
	q := model.DB.Where("slug = ?", slug)
	if !allowUnpublished {
		q = q.Where("published = ?", true)
	}
	if err := q.First(&page).Error; err != nil {
		return nil, ErrSitePageNotFound
	}
	page.Content = SanitizePostHTML(UnwrapContentGateTags(page.Content))
	return &page, nil
}

func (s *SitePageService) GetByID(id uint) (*model.SitePage, error) {
	var page model.SitePage
	if err := model.DB.First(&page, id).Error; err != nil {
		return nil, ErrSitePageNotFound
	}
	page.Content = SanitizePostHTML(UnwrapContentGateTags(page.Content))
	return &page, nil
}

type SitePageInput struct {
	Title        string `json:"title"`
	Slug         string `json:"slug"`
	Content      string `json:"content"`
	Published    bool   `json:"published"`
	SortOrder    int    `json:"sort_order"`
	ShowInFooter bool   `json:"show_in_footer"`
	ShowInNav    bool   `json:"show_in_nav"`
}

func (s *SitePageService) Create(in SitePageInput) (*model.SitePage, error) {
	page, err := s.normalizeInput(in)
	if err != nil {
		return nil, err
	}
	var exists int64
	model.DB.Model(&model.SitePage{}).Where("slug = ?", page.Slug).Count(&exists)
	if exists > 0 {
		return nil, ErrSitePageSlugUsed
	}
	if err := model.DB.Create(page).Error; err != nil {
		return nil, err
	}
	return page, nil
}

func (s *SitePageService) Update(id uint, in SitePageInput) error {
	page, err := s.GetByID(id)
	if err != nil {
		return err
	}
	next, err := s.normalizeInput(in)
	if err != nil {
		return err
	}
	var exists int64
	model.DB.Model(&model.SitePage{}).Where("slug = ? AND id <> ?", next.Slug, id).Count(&exists)
	if exists > 0 {
		return ErrSitePageSlugUsed
	}
	return model.DB.Model(page).Updates(map[string]interface{}{
		"title":          next.Title,
		"slug":           next.Slug,
		"content":        next.Content,
		"published":      next.Published,
		"sort_order":     next.SortOrder,
		"show_in_footer": next.ShowInFooter,
		"show_in_nav":    next.ShowInNav,
	}).Error
}

func (s *SitePageService) Delete(id uint) error {
	res := model.DB.Delete(&model.SitePage{}, id)
	if res.Error != nil {
		return res.Error
	}
	if res.RowsAffected == 0 {
		return ErrSitePageNotFound
	}
	return nil
}

// SetPublished 仅切换发布状态（列表快捷操作）
func (s *SitePageService) SetPublished(id uint, published bool) error {
	page, err := s.GetByID(id)
	if err != nil {
		return err
	}
	return model.DB.Model(page).Update("published", published).Error
}

func (s *SitePageService) ListSitemap(limit int) ([]model.SitePage, error) {
	if limit <= 0 {
		limit = 500
	}
	var rows []model.SitePage
	err := model.DB.Where("published = ?", true).
		Order("updated_at DESC").Limit(limit).Find(&rows).Error
	return rows, err
}

func (s *SitePageService) normalizeInput(in SitePageInput) (*model.SitePage, error) {
	title := s.filter.Filter(strings.TrimSpace(in.Title))
	slug, ok := NormalizePageSlug(in.Slug)
	if !ok {
		return nil, errors.New("slug 格式无效（2-64 位小写字母、数字、连字符）")
	}
	// 单页不支持登录/回复/积分可见：保存前剥离外壳，保留内部正文
	content := s.filter.Filter(SanitizePostHTML(UnwrapContentGateTags(in.Content)))
	if title == "" {
		return nil, errors.New("标题不能为空")
	}
	if content == "" {
		return nil, errors.New("正文不能为空")
	}
	return &model.SitePage{
		Title: title, Slug: slug, Content: content,
		Published: in.Published, SortOrder: in.SortOrder,
		ShowInFooter: in.ShowInFooter, ShowInNav: in.ShowInNav,
	}, nil
}
