import datetime
import os
import time
import requests
from api import API
from back_ground_module import CommonModule
import pandas as pd
from log_config import configure_task_logger, configure_error_task_logger

api_instance = API()
common_module = CommonModule()
# start_time = datetime.datetime.now()

# 获取已经配置好的常规日志记录器
logger = configure_task_logger()

# 获取已经配置好的错误任务日志记录器
error_task_logger = configure_error_task_logger()
output_dir = "output"  # 设置输出目录
os.makedirs(output_dir, exist_ok=True)

class NewExceptionTask:
    """
    SaaS异常回访
    """

    def __init__(self):
        self.exception_service_todo = None
        self.get_feature_usage = None
        self.saas_create_time = None
        self.index = None
        self.date_one = None
        self.data_yichang_S = None
        self.date_list = None
        self.Smart_detection = None
        self.service_remind = None
        self.NGV_data_list = None
        self.permissions_table = None
        self.staff_id_list = None
        self.json_list = []
        self.policy_recognition = None
        self.widget_list = None
        self.private_domain = None
        self.public_domain = None
        self.public_domain_list = None
        self.different_industries = None
        self.different_industries_list = None
        self.groupnotification = None
        self.fields_mapping = {
            "门店名称": "_widget_1748241895830",
            "联系人": "_widget_1748241895831",
            "开户时间": "_widget_1748241895839",
            "门店编码": "_widget_1748241895842",
            "联系方式": "_widget_1748241895832",
            "系统版本": "_widget_1748241895850",
            "公司名称": "_widget_1748241895844",
            "运营顾问": "_widget_1748246808679",
            "区域经理": "_widget_1748246808682",
            "公司等级": "_widget_1748241895846",
            "运营专家": "_widget_1748246808681",
            "操作模式E.L/E.S": "_widget_1748241895853",
            "活跃健康状态变化": "_widget_1748241895829",
            "初始日": "_widget_1748241895833",
            "推进日": "_widget_1748241895834",
            "异常跟进情况描述": "_widget_1748512176640",
            "异常变化原因": "_widget_1748512176641",
            "正常使用": "_widget_1748512176643",
            "门店原因": "_widget_1748512176645",
            "服务原因": "_widget_1748512176647",
            "产品原因": "_widget_1748512176649",
            "未正式切换": "_widget_1748512176651",
            "跟进状态": "_widget_1748512176655",
            "是否可激活": "_widget_1758615839701",
            "是否有续约风险": "_widget_1758615839703",
            "当前跟进人": "_widget_1748246808678",
            "激活策略": "_widget_1758615839717",
            "跟进时间": "_widget_1748512176654",
            "是否跟进完成": "_widget_1751273412737",
            "区域客服": "_widget_1748246808680",
            "大区": "_widget_1748241895847",
            "省": "_widget_1748241895848",
            "城市": "_widget_1748241895855",
            "门店类型": "_widget_1748241895849",
            "saas客户类型": "_widget_1748241895851",
            "门店阶段": "_widget_1748241895852",
            "提交人": "creator",
            "提交时间": "createTime",
            "更新时间": "updateTime"
        }

    def calculate_date_one(self, start_offset=0):
        """
        计算从当前日期（或指定偏移量的日期）开始，往前遍历遇到date_list中日期的次数。

        参数:
        - start_offset: 从当前日期起始的天数偏移量，默认为0（即今天）。负数表示过去，正数表示未来。

        返回:
        - date_one: 遍历到date_list中日期的次数。
        """
        jdy_date = datetime.datetime.now().strftime("%Y-%m-%d")
        jdy_start_time = datetime.datetime.now().strftime("%Y-%m-%d ")
        # 设置起始日期
        now_time = datetime.datetime.now() + datetime.timedelta(days=start_offset)

        # 初始化计数器
        date_one = 1
        print("当前日期：", now_time.strftime("%Y-%m-%d"))
        # 检查起始日期是否在date_list中
        if now_time.strftime("%Y-%m-%d") in self.date_list:
            date_one = 0
            print("开始次数：", date_one)

        else:
            # 遍历日期
            for i in range(1, 10):
                new_date = now_time + datetime.timedelta(days=-i)
                new_date_str = new_date.strftime("%Y-%m-%d")
                print("遍历日期：", new_date_str)
                if new_date_str in self.date_list:
                    date_one += 1
                    print("节假日期：", new_date_str)
                else:
                    break

        print("遍历次数：", date_one)
        return date_one

    @staticmethod
    def download_url_content(url, save_path):
        """
        下载指定 URL 的内容并保存到本地文件。

        :param url: 要下载内容的 URL
        :param save_path: 保存文件的路径
        """
        try:
            # 发送 GET 请求以获取内容
            response = requests.get(url, stream=True)
            response.raise_for_status()  # 如果响应状态码不是 200，抛出异常

            # 确保保存目录存在
            os.makedirs(os.path.dirname(save_path), exist_ok=True)

            # 将内容写入文件
            with open(save_path, 'wb') as file:
                for chunk in response.iter_content(chunk_size=8192):  # 分块写入，避免占用过多内存
                    if chunk:  # 过滤掉空块
                        file.write(chunk)

            print(f"文件已成功保存到 {save_path}")

        except requests.exceptions.RequestException as e:
            print(f"下载失败: {e}")
        except Exception as e:
            print(f"发生错误: {e}")

    def load_all_data(self):
        """加载所有必要的数据表"""
        # 省市区人员关系表
        payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "676512ac3e54dc3159460c0a"}
        json_dict = api_instance.entry_data_list(payload)
        self.json_list = json_dict.get("data")

        # 获取简道云员工id
        payload = {"api_key": "6694d3c4fcb69ca9a111a6c4",
                   "entry_id": "6769204a1902c9341340a1bc",
                   }
        staff_id = api_instance.entry_data_list(payload)
        self.staff_id_list = staff_id.get("data")  # api请求格式，将数据封装在data字典里

        # 获取NGV数据
        payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "675bb02bd2d53c2034c665e4"}
        self.NGV_data_list = api_instance.entry_data_list(payload).get("data", [])
        # print("NGV获取后的类型：", type(self.NGV_data_list))

        # 获取异常服务待办(添加过滤进行中的订单)
        payload = {"api_key": "675b900991ad2491c69389ca", "entry_id": "68340de79f116c0b66b6b0cc","filter":{"rel":"and","cond":[{ "field": "flowState", "type":"flowstate", "method":"eq","value":[0] }]}}
        self.exception_service_todo = api_instance.entry_data_list(payload).get("data", [])
        # print(self.exception_service_todo)

    @staticmethod
    def build_index(json_list):
        index = {}
        for json_item in json_list:
            try:
                key = (json_item['_widget_1734677164861'], json_item['_widget_1734677164862'],
                       json_item['_widget_1734677164863'])  # 省市区
                if '_widget_1734677164870' not in json_item:  # 异常回访客服
                    raise KeyError("缺少 '异常回访客服' 键")
                index[key] = json_item
            except KeyError as e:
                print(f"警告：{e}，跳过该条记录: {json_item}")
                continue
        print('index', index)
        return index

    @staticmethod
    def find_customer_service(province_name, city_name, area_name, index):
        key = (province_name, city_name, area_name)
        # print(index)
        if key not in index:
            return "数据缺失: 未找到对应的异常回访客服"

        return index[key]

    @staticmethod
    def get_staff_id(row_item, name):
        """辅助函数，用于获取员工ID"""
        if str(row_item["_widget_1734942794144"]) == str(name):  # 检查姓名是否匹配
            return row_item["_widget_1734942794145"]  # 返回员工ID
        return None

    def assign_customer_service(self, province_name, city_name, area_name, index):
        """根据省市区派发给异常回访客服"""
        # try:
        customer_service_info = self.find_customer_service(province_name, city_name, area_name, index)
        customer_service = customer_service_info.get('_widget_1734677164870', {}).get('username')  # 异常回访客服
        return customer_service
        # except Exception as e:
        #     print(f"Error finding customer service: {e}")
        #     return "分配失败，请检查", "分配失败，请检查", "分配失败，请检查"

    def main(self):

        task_start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        all_data =[]
        try:
            self.load_all_data()

            data = common_module.get_yichang_details(days_back=1)
            self.data_yichang_S = pd.DataFrame() if data is None or data.empty else data.astype(str)
            self.index = self.build_index(self.json_list)

            logger.info("开始运行SaaS异常回访")
            if self.data_yichang_S.empty:
                logger.info("未获取到数据或数据为空")
                common_module.send_task_status(task_start_time, "异常服务待办派发")
                return

            data_yichang = self.data_yichang_S.copy()
            # data_yichang.to_csv(os.path.join(output_dir,"data_yichang.csv"), index=False)

            def replace_values(series):
                # 使用条件判断来进行替换
                return series.apply(lambda x: '' if pd.isna(x) or x in ['NA', 'None', ''] else x)

            # 对整个DataFrame的所有列应用替换函数
            data_yichang = data_yichang.apply(replace_values)

            for index_num, row in data_yichang.iterrows():  # 对过滤后的每一条进行派发
                try:
                    # 每次循环前清空省市区变量
                    province_name = None
                    city_name = None
                    area_name = None

                    is_pass = False
                    for exception_service in self.exception_service_todo :
                        # 通过查询筛选进行中的逻辑
                        if exception_service['_widget_1748241895842'] == row['org_code']:
                            is_pass = True
                            break

                    if is_pass:
                        logger.info(f"已存在待办，跳过该条记录: {row}")
                        continue

                    payload_dict = {}

                    distribution_date = datetime.datetime.now(datetime.timezone.utc)
                    distribution_date = distribution_date.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'

                    date_obj1 = datetime.datetime.strptime(row["init_day"], "%Y%m%d").strftime("%Y-%m-%d")
                    date_obj2 = datetime.datetime.strptime(row["push_day"], "%Y%m%d").strftime("%Y-%m-%d")

                    NGV_roles = {
                        'service_impl_principal': row['service_impl_principal'],  # 运营负责人
                        'area_manager': row['area_manager'],  # 区域经理
                        'technician': row['technician'],  # 运营专家
                    }
                    for role, name in NGV_roles.items():  # 寻找对应的员工ID
                        for row_item in self.staff_id_list:
                            staff_id = self.get_staff_id(row_item, name)
                            if staff_id:
                                NGV_roles[role] = staff_id
                                break  # 找到后退出循环
                        else:
                            NGV_roles[role] = None  # 如果没有找到对应的员工ID
                    relationship_manager, area_manager, technician = [NGV_roles[role] for role in
                                                                      ['service_impl_principal',
                                                                       'area_manager',
                                                                       'technician']]

                    UUid = time.strftime("%Y%m%d%H%M%S", time.localtime())

                    NGV_data_id = None
                    reason = None
                    create_exception =None
                    create_date =  None
                    
                    # 优先从 data_yichang_S 获取省市区信息
                    province_name = row.get('province_name')
                    city_name = row.get('city_name')
                    area_name = row.get('area_name') if 'area_name' in row else row.get('district_name')
                    
                    # 检查省市区是否完整（省市区是一体的，任意一个缺失就需要从NGV获取）
                    use_ngv_location = False
                    if (not province_name or province_name in ['', 'None', 'NA'] or
                        not city_name or city_name in ['', 'None', 'NA'] or
                        not area_name or area_name in ['', 'None', 'NA']):
                        use_ngv_location = True
                        logger.info(f"门店 {row['org_code']} 的省市区信息不完整，将从NGV_data_list获取")
                    
                    # 获取关联数据
                    for NGV_Data in self.NGV_data_list:
                        # NGV_Data = NGV_Data.get("data")
                        if row["org_code"] == NGV_Data.get("_widget_1734062123071"):  # 门店编码
                            NGV_data_id = NGV_Data.get("_id")
                            
                            # 如果需要从 NGV_data_list 获取省市区信息
                            if use_ngv_location:
                                province_name = NGV_Data.get("_widget_1734062123090")
                                city_name = NGV_Data.get("_widget_1734062123092")
                                area_name = NGV_Data.get("_widget_1734062123094")
                                logger.info(f"【从NGV获取省市区】门店 {row['org_code']}: {province_name}, {city_name}, {area_name}")
                            
                            # 门店原因
                            reason = NGV_Data.get("_widget_1758617393828")
                            logger.info(f"获取关联数据成功:{NGV_data_id}, {province_name}, {city_name}, {area_name}")
                            # 是否生成异常待办
                            create_exception = NGV_Data.get("_widget_1758769279995")
                            # 获取上线日期（文本）
                            create_date = NGV_Data.get("_widget_1734062123176")
                            break  # 找到匹配的数据后退出循环

                    # 判断门店原因
                    # if reason in ["门店倒闭", "门店转让", "加盟其他连锁","切换竞品","虚拟门店","重新开户","已退款","二套系统"]:
                    #     continue

                    # 判断是否继续生成异常待办
                    if create_exception == "否":
                        continue
                    # 新增：检查 create_date_str 是否存在且有效
                    if not create_date:
                        logger.warning("上线日期为空，跳过该记录")
                        continue

                    # 定义可能的日期格式（灵活应对不同格式）
                    date_formats = [
                        "%Y-%m-%d %H:%M:%S",  # 含时间
                        "%Y-%m-%d",  # 仅日期
                        "%Y/%m/%d",
                        "%Y/%m/%d %H:%M:%S"
                    ]

                    parsed_date = None
                    for fmt in date_formats:
                        try:
                            parsed_date = datetime.datetime.strptime(create_date.strip(), fmt).date()
                            logger.debug(f"使用格式 {fmt} 成功解析日期: {parsed_date}")
                            break
                        except ValueError:
                            continue

                    if parsed_date is None:
                        logger.error(f"无法解析上线日期: '{create_date}'，支持的格式: %Y-%m-%d, %Y-%m-%d %H:%M:%S 等")
                        continue  # 解析失败，跳过

                    # 使用解析后的日期进行判断
                    now_date = datetime.date.today()
                    delta = now_date - parsed_date
                    days_diff = delta.days

                    if days_diff > 30:
                        logger.info(f"上线日期 {parsed_date} 超过30天（{days_diff}天），生成待办")
                        # ✅ 继续后续待办创建逻辑
                    else:
                        logger.info(f"上线日期 {parsed_date} 在30天内，跳过处理")
                        continue


                    if not NGV_data_id:
                        logger.warning(f"未找到关联数据，请检查门店编码: {row['org_code']}")

                    # 根据省市区派发给异常回访客服
                    # 检查省市区是否都有值，如果有任何一个为空，则客服为空
                    if (not province_name or province_name in ['', 'None', 'NA'] or
                        not city_name or city_name in ['', 'None', 'NA'] or
                        not area_name or area_name in ['', 'None', 'NA']):
                        customer_service = None
                        logger.warning(f"【省市区信息缺失】门店 {row['org_code']} 省市区信息不完整，异常回访客服设置为空")
                        logger.warning(f"省: {province_name}, 市: {city_name}, 区: {area_name}")
                    else:
                        customer_service = self.assign_customer_service(province_name, city_name, area_name, self.index)
                        logger.info(f"【派发客服】门店 {row['org_code']} 派发给客服: {customer_service}")

                    payload_dict.update({
                        "_widget_1748241895829": {"value": row["health_warning_info"]},  # 活跃健康状态变化

                        "_widget_1748241895830": {"value": row["org_name"]},  # 门店名称

                        "_widget_1748241895831": {"value": row["contacts"]},  # 联系人

                        "_widget_1748241895832": {"value": row['contact_mobile']},  # 联系方式

                        "_widget_1748241895833": {
                            "value": int(time.mktime(time.strptime(date_obj1, "%Y-%m-%d")) * 1000) if row[
                                                                                                          "init_day"] != '' else ''},
                        # 初始日

                        "_widget_1748241895834": {
                            "value": int(time.mktime(time.strptime(date_obj2, "%Y-%m-%d")) * 1000) if row[
                                                                                                          "push_day"] != '' else ''},
                        # 推进日

                        "_widget_1748246808678": {"value": customer_service},  # 当前跟进人
                        # "_widget_1748246808678": {"value": "083726094935447433"},  # 当前跟进人

                        "_widget_1748246808679": {"value": relationship_manager},  # 运营负责人

                        "_widget_1748246808680": {"value": customer_service},  # 区域客服

                        "_widget_1748241895839": {
                            "value": int(time.mktime(time.strptime(row["saas_create_time"], "%Y-%m-%d")) * 1000) if row[
                                                                                                                        "saas_create_time"] != '' else ''},
                        # 开户时间

                        "_widget_1748246808681": {"value": technician},  # 技术专家

                        "_widget_1748246808682": {"value": area_manager},  # 区域经理

                        "_widget_1748241895842": {"value": row['org_code']},  # 门店编码

                        "_widget_1748241895844": {"value": row['group_name']},  # 公司名称

                        "_widget_1748241895846": {"value": row['group_grade']},  # 公司等级

                        "_widget_1748241895847": {"value": row['region_name']},  # 大区

                        "_widget_1748241895848": {"value": row['province_name']},  # 省

                        "_widget_1748241895849": {"value": row['org_type']},  # 门店类型

                        "_widget_1748241895850": {"value": row['saas_edition_fmt']},  # 系统版本

                        "_widget_1748241895851": {"value": row['saas_customer_type']},  # saas客户类型

                        "_widget_1748241895852": {"value": row['org_stage']},  # 门店阶段

                        "_widget_1748241895853": {"value": row['contact_mobile']},  # 操作模式E.L/E.S

                        "_widget_1748241895855": {"value": row['city_name']},  # 城市

                        "_widget_1748247754304": {"value": NGV_data_id},  # 数据id

                        "_widget_1748512176655": {"value": "未处理"},  # 跟进状态

                    })

                    routine_follow_up_payload = {
                        "api_key": "675b900991ad2491c69389ca",
                        "entry_id": "68340de79f116c0b66b6b0cc",  # 异常服务跟进待办
                        "is_start_workflow": "true",
                        "data": payload_dict,
                        "transaction_id": UUid
                    }
                    all_data.append(routine_follow_up_payload)

                    res = api_instance.data_batch_create(routine_follow_up_payload)
                    logger.info(f"创建结果：{res}")

                except:
                    pass
            # ndf = pd.DataFrame(all_data)
            # ndf.to_csv(os.path.join(output_dir, "异常派发.csv"))
            common_module.send_task_status(task_start_time, "异常服务待办派发")
        except Exception as e:
            error_task_logger.error(f"异常服务待办派发执行时发生异常: {e}")
            common_module.send_task_error(task_start_time, "异常服务待办派发", str(e))


if __name__ == '__main__':
    start = NewExceptionTask()
    start.main()
