import json
import os
import re
from pathlib import Path
from urllib.parse import unquote, urlparse

import requests
from loguru import logger
from requests_toolbelt import MultipartEncoder

from core.config import base_fastgpt_url, base_backend_url, outer_backend_url


def fastgpt_openai_chat(url, token, model, chat_id, file_url, text, stream=True):
    data = {
        "chatId": chat_id,
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "file_url", "name": "文件", "url": file_url},
                    {
                        "type": "text",
                        "text": text,
                    },
                ],
            }
        ],
        "model": model,
        "stream": stream,
    }
    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}
    response = requests.post(
        url=url,
        headers=headers,
        data=json.dumps(data),
        stream=True,
        timeout=(60000, 60000),
    )
    rsp = ""
    if stream:
        for chunk in response.iter_content(8192):
            try:
                chunk = chunk.decode("utf-8")
                if "data: [DONE]" in chunk:
                    break
                # logger.info(chunk)
                stream_rsp = json.loads(chunk[6:])
                rsp += stream_rsp.get("choices")[0]["delta"]["content"]
            except Exception as e:
                logger.error(f"error decode:{e} chunk:{chunk}")
    else:
        # print(response.text)
        json_rsp = json.loads(response.text)
        rsp = json_rsp.get("choices")[0]["message"]["content"]
    return rsp


def upload_file(path, input_url_to_inner=True, output_url_to_inner=False) -> str:
    # 登录获取token
    login_data = {"username": "admin", "password": "admin@jpai.com"}
    login_url = f"{base_backend_url}/admin-api/system/auth/login"
    response = requests.post(
        url=login_url,
        headers={"Content-Type": "application/json"},
        data=json.dumps(login_data),
    )
    try:
        token = json.loads(response.text).get("data").get("accessToken")
    except Exception as e:
        logger.error(f"后端登录异常:{e}")
    # logger.info(f"上传Token: {token}")
    # 上传文件
    upload_url = f"{base_backend_url}/admin-api/infra/file/upload"
    m = MultipartEncoder(fields={"file": (os.path.basename(path), open(path, "rb"))})
    response = requests.post(
        url=upload_url,
        headers={"Content-Type": m.content_type, "Authorization": token},
        data=m,
    )
    res = json.loads(response.text).get("data")
    if res:
        return res
    else:
        raise Exception(f"上传{path}失败 Response text: {response.text}")


def _download_basename(filename: str) -> str:
    filename = unquote(filename.strip().strip('"'))
    filename = filename.replace("\\", "/")
    return Path(filename).name or "downloaded_file"


def _resolve_download_filename(url: str, response: requests.Response) -> str:
    content_disposition = response.headers.get("content-disposition", "")
    if content_disposition:
        match = re.search(
            r"filename\*=(?:UTF-8''|utf-8'')?([^;]+)", content_disposition
        )
        if match:
            return _download_basename(match.group(1))

        match = re.search(r'filename="?([^";]+)"?', content_disposition)
        if match:
            return _download_basename(match.group(1))

    url_filename = _download_basename(urlparse(url).path)
    if url_filename:
        return url_filename

    return "downloaded_file"


# 下载url到本地path
def download_file(url, path, input_url_to_inner=True):
    if not url.startswith("http:"):
        url = base_fastgpt_url + url
    url = url.replace(outer_backend_url, base_backend_url)
    logger.info(f"url准备下载:{url}")
    # 发送一个HTTP请求到URL
    response = requests.get(url)
    # 确保请求成功
    if response.status_code == 200:
        target_path = Path(path)
        if target_path.exists() and target_path.is_dir():
            target_path = target_path / _resolve_download_filename(url, response)

        target_path.parent.mkdir(parents=True, exist_ok=True)

        # 打开本地文件，准备写入数据
        with open(target_path, "wb") as f:
            # 写入响应的内容
            f.write(response.content)
        logger.info(f"{url}文件下载成功，保存到{target_path}")
        return str(target_path)
    else:
        logger.error(f"{url}文件下载失败. HTTP Status Code: {response.status_code}")
        return None


def url_replace_fastgpt(origin: str):
    if not origin.startswith("http:"):
        origin = base_fastgpt_url + origin
    return origin


if __name__ == "__main__":
    # d = '/home/ccran/file.docx'
    d = "/home/ccran/lufa-contract/tmp/default.json"
    print(upload_file(d))
