package api

import (
	"context"
	"fmt"
	"html"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/chromedp/cdproto/page"
	"github.com/chromedp/chromedp"
	"github.com/yuin/goldmark"
	"u-desk/internal/common"
)

// PdfExportRequest PDF导出请求结构体
type PdfExportRequest struct {
	Content    string `json:"content"`    // Markdown/HTML内容
	Title      string `json:"title"`      // PDF标题
	FileName   string `json:"fileName"`   // 文件名（不含扩展名）
	FontSize   int    `json:"fontSize"`   // 字体大小
	PageWidth  int    `json:"pageWidth"`  // 页面宽度（mm）
	PageHeight int    `json:"pageHeight"` // 页面高度（mm）
}

// PdfExportResponse PDF导出响应结构体
type PdfExportResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
	Path    string `json:"path"`  // PDF文件保存路径
	Size    int64  `json:"size"`  // 文件大小（字节）
}

// PdfAPI PDF导出API
type PdfAPI struct {
	// 可以在这里添加依赖，如文件系统服务等
}

// NewPdfAPI 创建PDF导出API
func NewPdfAPI() (*PdfAPI, error) {
	return &PdfAPI{}, nil
}

// ExportMarkdownToPDF 将Markdown内容导出为PDF - 使用chromedp实现
func (api *PdfAPI) ExportMarkdownToPDF(req PdfExportRequest) (*PdfExportResponse, error) {
	// 验证参数
	if strings.TrimSpace(req.Content) == "" {
		return nil, fmt.Errorf("内容不能为空")
	}

	if strings.TrimSpace(req.FileName) == "" {
		req.FileName = "document_" + time.Now().Format("20060102_150405")
	}

	if req.FontSize <= 0 {
		req.FontSize = 12
	}

	// 设置默认页面尺寸（A4）
	if req.PageWidth <= 0 {
		req.PageWidth = 210
	}
	if req.PageHeight <= 0 {
		req.PageHeight = 297
	}

	// 将Markdown转换为HTML
	htmlContent := api.markdownToHTML(req.Content, req.Title, req.FontSize)

	// 使用chromedp生成PDF
	pdfBuffer, err := api.generatePDFFromHTML(htmlContent, req.Title, req.PageWidth, req.PageHeight)
	if err != nil {
		return nil, fmt.Errorf("生成PDF失败: %v", err)
	}

	// 生成文件名
	if !strings.HasSuffix(strings.ToLower(req.FileName), ".pdf") {
		req.FileName += ".pdf"
	}

	// 获取用户桌面目录作为默认保存位置
	saveDir := api.getDesktopDirectory()

	// 确保目录存在
	if err := os.MkdirAll(saveDir, 0755); err != nil {
		return nil, fmt.Errorf("创建目录失败: %v", err)
	}

	// 完整保存路径
	savePath := filepath.Join(saveDir, filepath.Base(req.FileName))

	// 保存PDF文件
	err = os.WriteFile(savePath, pdfBuffer, 0644)
	if err != nil {
		return nil, fmt.Errorf("保存PDF文件失败: %v", err)
	}

	// 获取文件信息
	fileInfo, err := os.Stat(savePath)
	if err != nil {
		return nil, fmt.Errorf("获取文件信息失败: %v", err)
	}

	// 返回成功响应
	return &PdfExportResponse{
		Success: true,
		Message: "PDF生成成功",
		Path:    savePath,
		Size:    fileInfo.Size(),
	}, nil
}

// markdownToHTML 将Markdown转换为HTML
func (api *PdfAPI) markdownToHTML(markdownContent string, title string, fontSize int) string {
	// 基础HTML模板
	htmlTemplate := `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 800px;
            margin: 0 auto;
            padding: 40px 20px;
            font-size: %dpx;
        }
        h1, h2, h3, h4, h5, h6 {
            margin-top: 24px;
            margin-bottom: 16px;
            font-weight: 600;
            line-height: 1.25;
        }
        h1 {
            font-size: 2em;
            border-bottom: 1px solid #eaecef;
            padding-bottom: 0.3em;
        }
        h2 {
            font-size: 1.5em;
            border-bottom: 1px solid #eaecef;
            padding-bottom: 0.3em;
        }
        h3 {
            font-size: 1.25em;
        }
        h4 {
            font-size: 1em;
        }
        h5 {
            font-size: 0.875em;
        }
        h6 {
            font-size: 0.85em;
            color: #6a737d;
        }
        p {
            margin-bottom: 16px;
        }
        blockquote {
            margin: 0 0 16px;
            padding: 0 1em;
            color: #6a737d;
            border-left: 0.25em solid #dfe2e5;
        }
        ul, ol {
            padding-left: 2em;
            margin-bottom: 16px;
        }
        li {
            margin-bottom: 4px;
        }
        code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            background-color: rgba(27,31,35,0.05);
            border-radius: 3px;
            font-size: 85%;
            margin: 0;
            padding: 0.2em 0.4em;
        }
        pre {
            background-color: #f6f8fa;
            border-radius: 3px;
            padding: 16px;
            overflow: auto;
            margin-bottom: 16px;
        }
        pre code {
            background-color: transparent;
            padding: 0;
            margin: 0;
            font-size: 100%;
        }
        table {
            border-collapse: collapse;
            width: 100%;
            margin-bottom: 16px;
            border: 1px solid #dfe2e5;
        }
        th, td {
            padding: 8px 12px;
            border: 1px solid #dfe2e5;
            text-align: left;
        }
        th {
            background-color: #f6f8fa;
            font-weight: 600;
        }
        img {
            max-width: 100%;
            height: auto;
            margin: 16px 0;
        }
        hr {
            height: 0.25em;
            padding: 0;
            margin: 24px 0;
            background-color: #e1e4e8;
            border: 0;
        }
        .title {
            text-align: center;
            margin-bottom: 32px;
            font-size: 1.5em;
            color: #2c3e50;
        }
    </style>
</head>
<body>
    <div class="title">%s</div>
    %s
</body>
</html>`

	// 标题处理
	docTitle := ""
	if title != "" {
		docTitle = html.EscapeString(title)
	} else {
		docTitle = "文档"
	}

	// Markdown转HTML（使用goldmark）
	var htmlContent string
	var htmlBuf strings.Builder
	if err := goldmark.Convert([]byte(markdownContent), &htmlBuf); err != nil {
		htmlContent = "<p>Markdown 解析失败</p>"
	} else {
		htmlContent = htmlBuf.String()
	}

	// 生成完整的HTML
	fullHTML := fmt.Sprintf(htmlTemplate, fontSize, docTitle, htmlContent)

	return fullHTML
}

// generatePDFFromHTML 使用chromedp从HTML生成PDF
func (api *PdfAPI) generatePDFFromHTML(htmlContent, title string, pageWidth, pageHeight int) ([]byte, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	// 配置chromedp选项
	opts := []chromedp.ExecAllocatorOption{
		chromedp.Flag("headless", true),
		chromedp.Flag("disable-gpu", true),
		chromedp.Flag("no-sandbox", true),
		chromedp.Flag("disable-dev-shm-usage", true),
		chromedp.Flag("disable-software-rasterizer", true),
		chromedp.Flag("disable-extensions", true),
		chromedp.Flag("disable-notifications", true),
	}

	// 在Windows上设置Chrome路径
	if common.IsWindows() {
		// 常见的Windows Chrome路径
		chromePaths := []string{
			"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
			"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
			"C:\\Users\\" + os.Getenv("USERNAME") + "\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
		}

		for _, path := range chromePaths {
			if _, err := os.Stat(path); err == nil {
				opts = append(opts, chromedp.ExecPath(path))
				break
			}
		}
	}

	// 创建执行分配器上下文
	allocCtx, allocCancel := chromedp.NewExecAllocator(ctx, opts...)
	defer allocCancel()

	// 创建chromedp上下文
	chromeCtx, chromeCancel := chromedp.NewContext(allocCtx)
	defer chromeCancel()

	// 创建一个临时的目录用于PDF生成
	tempDir, err := os.MkdirTemp("", "pdf_gen")
	if err != nil {
		return nil, fmt.Errorf("创建临时目录失败: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// 将HTML写入临时文件
	htmlFile := filepath.Join(tempDir, "document.html")
	if err := os.WriteFile(htmlFile, []byte(htmlContent), 0644); err != nil {
		return nil, fmt.Errorf("写入HTML文件失败: %v", err)
	}

	var buf []byte

	// 使用 file URL 加载本地HTML文件
	err = chromedp.Run(chromeCtx,
		// 导航到HTML文件
		chromedp.Navigate("file://"+htmlFile),
		// 等待页面加载完成
		chromedp.WaitReady("body"),
		// 打印到PDF
		chromedp.ActionFunc(func(ctx context.Context) error {
			// 设置页面打印参数
			printToPDF := page.PrintToPDF().
				WithPrintBackground(true).
				WithLandscape(false).
				WithMarginTop(0).
				WithMarginBottom(0).
				WithMarginLeft(0).
				WithMarginRight(0).
				WithPaperWidth(float64(pageWidth) / 25.4). // mm to inches
				WithPaperHeight(float64(pageHeight) / 25.4) // mm to inches

			// 执行打印并获取PDF数据
			var err error
			buf, _, err = printToPDF.Do(ctx)
			return err
		}),
	)

	if err != nil {
		return nil, fmt.Errorf("chromedp执行失败: %v", err)
	}

	return buf, nil
}

// getDesktopDirectory 获取用户桌面目录
func (api *PdfAPI) getDesktopDirectory() string {
	// Windows系统
	if common.IsWindows() {
		home := os.Getenv("USERPROFILE")
		if home != "" {
			return filepath.Join(home, "Desktop")
		}
	}
	
	// Linux/Mac系统
	home := os.Getenv("HOME")
	if home != "" {
		return filepath.Join(home, "Desktop")
	}
	
	// 备用：当前目录
	return "."
}

// SelectDirectory 选择保存目录（简化版，实际应该使用Wails runtime）
func (api *PdfAPI) SelectDirectory() (string, error) {
	// 简化版：直接返回桌面目录
	desktop := api.getDesktopDirectory()
	if desktop == "." {
		return "", fmt.Errorf("无法确定默认目录")
	}
	return desktop, nil
}