package qywx

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"path"
	"time"
)

type Other struct {
	auth *Auth
}

func NewOther(auth *Auth) *Other {
	return &Other{

		auth: auth,
	}
}

func (g *Other) UploadMediaWithUrl(ctx context.Context, fileUrl, mediaType, corpid, corpsecret string) (uploadRes *UploadMediaRes, err error) {
	// 1. 获取AccessToken
	auth, err := g.auth.GetAccessToken(ctx, corpid, corpsecret)
	if err != nil {
		return nil, fmt.Errorf("获取AccessToken失败: %v", err)
	}

	// 2. 下载文件
	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Get(fileUrl)
	if err != nil {
		return nil, fmt.Errorf("下载文件失败: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("下载文件状态码错误: %d", resp.StatusCode)
	}

	// 3. 准备上传请求（修正点：使用正确的上传API）
	uploadUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s",
		auth.AccessToken, mediaType)

	// 4. 创建multipart表单
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	// 从URL提取文件名（或使用默认名）
	filename := path.Base(fileUrl)
	if filename == "/" || filename == "." {
		filename = fmt.Sprintf("file_%d.dat", time.Now().Unix())
	}

	part, err := writer.CreateFormFile("media", filename)
	if err != nil {
		return nil, fmt.Errorf("创建表单文件失败: %v", err)
	}

	// 5. 流式传输文件内容
	if _, err = io.Copy(part, resp.Body); err != nil {
		return nil, fmt.Errorf("写入文件内容失败: %v", err)
	}

	// 6. 关闭writer
	if err = writer.Close(); err != nil {
		return nil, fmt.Errorf("关闭writer失败: %v", err)
	}

	// 7. 发送上传请求
	req, err := http.NewRequest("POST", uploadUrl, body)
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())

	uploadResp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("上传请求失败: %v", err)
	}
	defer uploadResp.Body.Close()

	// 8. 解析响应
	respBody, err := io.ReadAll(uploadResp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	if err = json.Unmarshal(respBody, &uploadRes); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	if uploadRes.Errcode != 0 {
		return nil, fmt.Errorf("上传失败 [code=%d]: %s", uploadRes.Errcode, uploadRes.Errmsg)
	}

	return
}
