# coding: utf-8

from __future__ import absolute_import, division, print_function, unicode_literals

import datetime
from typing import TYPE_CHECKING, List

from dateutil import parser
from six.moves.urllib.parse import urlencode

from miwork.dt_code import SimpleUser
from miwork.dt_help import make_datatype
from miwork.dt_meeting_room import Building, Room, RoomFreeBusy
from miwork.helper import converter_enum, datetime_format_rfc3339

if TYPE_CHECKING:
    from miwork.api import OpenLark


class TimeZoneChina(datetime.tzinfo):
    _offset = datetime.timedelta(hours=8)
    _dst = datetime.timedelta(0)
    _name = "+08"

    def utcoffset(self, dt):
        return self.__class__._offset

    def dst(self, dt):
        return self.__class__._dst

    def tzname(self, dt):
        return self.__class__._name


class APIMeetingRoomMixin(object):
    def get_building_list(self, page_size=10, page_token='', order_by='', fields=None):
        """获取建筑物列表

        :type self: OpenLark
        :param page_size: 可选参数，请求期望返回的建筑物数量，不足则返回全部，该值默认为 10，最大为 100
        :type page_size: int
        :param page_token: 可选参数，用于标记当前请求的页数，将返回以当前页开始，往后 page_size 个元素
        :type page_token: str
        :param order_by: 可选参数，提供用于对名称进行升序/降序排序的方式查询，可选项有："name-asc,name-desc"，传入其他字符串不做处理，默认无序
        :type order_by: str
        :param fields: 可选参数，可选字段有："id,name,description,floors"，默认返回所有字段
        :type fields: list[str]
        :return: has_more, page_token, 建筑物列表
        :rtype: (bool, str, list[Building])

        该接口用于获取本企业下的建筑物（办公大楼）。

        https://open.feishu.cn/document/ukTMukTMukTM/ugzNyUjL4cjM14CO3ITN
        """
        if page_size > 100:
            page_size = 100
        elif page_size <= 0:
            page_size = 10

        params = {
            'page_size': page_size,
        }
        if page_token:
            params['page_token'] = page_token
        if order_by:
            params['order_by'] = order_by
        if fields:
            params['fields'] = ','.join(fields)

        url = self._gen_request_url('/open-apis/meeting_room/building/list?{}'.format(urlencode(params)))
        res = self._get(url, with_tenant_token=True)
        data = res['data']

        has_more = data.get('has_more', False)
        page_token = data.get('page_token', '')
        building_list = [make_datatype(Building, i) for i in data.get('buildings', [])]
        return has_more, page_token, building_list

    def batch_get_building(self, building_ids, fields=None):
        """查询建筑物详情

        :type self: OpenLark
        :param building_ids: 必须参数，用于查询指定建筑物的ID列表
        :type building_ids: list[str]
        :param fields: 可选参数，用于指定返回的字段名，可选字段有："id,name,description,floors"，默认返回所有字段
        :return: 建筑物列表
        :rtype: list[Building]

        https://open.feishu.cn/document/ukTMukTMukTM/ukzNyUjL5cjM14SO3ITN
        """
        params = {
            'building_ids': building_ids,
        }
        if fields:
            params['fields'] = ','.join(fields)

        url = self._gen_request_url(
            '/open-apis/meeting_room/building/batch_get?{}'.format(urlencode(params, doseq=True)))

        res = self._get(url, with_tenant_token=True)
        data = res.get('data', {})
        buildings = data.get('buildings', [])
        building_list = [make_datatype(Building, i) for i in buildings]

        return building_list

    def get_room_list(self, building_id, page_size=100, page_token='', order_by='', fields=None):
        """获取会议室列表

        :type self: OpenLark
        :param building_id: 被查询的建筑物ID
        :type building_id: str
        :param page_size: 请求期望返回的会议室数量，不足则返回全部，该值默认为 100，最大为 1000
        :type page_size: int
        :param page_token: 用于标记当前请求的页数，将返回以当前页开始，往后 page_size 个元素
        :type page_token: str
        :param order_by: 提供用于对名称/楼层进行升序/降序排序的方式查询，可选项有："name-asc,name-desc,floor_name-asc,
                         floor_name-desc"，传入其他字符串不做处理，默认无序
        :type order_by: str
        :param fields: 可选字段有："id,name,description,capacity,building_id,building_name,floor_name,is_disabled,
                       display_id"，默认返回所有字段
        :type fields: list[str]
        :return: has_more, page_token, 会议室列表
        :rtype: (bool, str, list[Room])

        https://open.feishu.cn/document/ukTMukTMukTM/uADOyUjLwgjM14CM4ITN
        """
        if page_size > 1000:
            page_size = 1000
        elif page_size <= 0:
            page_size = 100

        params = {
            'building_id': building_id,
            'page_size': page_size
        }
        if page_token:
            params['page_token'] = page_token
        if order_by:
            params['order_by'] = order_by
        if fields:
            params['fields'] = ','.join(fields)

        url = self._gen_request_url('/open-apis/meeting_room/room/list?{}'.format(urlencode(params)))
        res = self._get(url, with_tenant_token=True)
        data = res.get('data', {})
        rooms = data.get('rooms', [])

        has_more = data.get('has_more', False)
        page_token = data.get('page_token', '')
        room_list = [make_datatype(Room, i) for i in rooms]
        return has_more, page_token, room_list

    def batch_get_room_list(self, room_ids, fields=None):
        """查询会议室详情

        :type self: OpenLark
        :param room_ids: 用于查询指定会议室的ID列表
        :type room_ids: List[str]
        :param fields: 可选字段有："id,name,description,capacity,building_id,building_name,floor_name,is_disabled,
                       display_id"，默认返回所有字段
        :return: 会议室列表
        :rtype: list[Room]

        https://open.feishu.cn/document/ukTMukTMukTM/uEDOyUjLxgjM14SM4ITN
        """
        params = {
            'room_ids': room_ids,
        }
        if fields:
            params['fields'] = ','.join(fields)

        url = self._gen_request_url('/open-apis/meeting_room/room/batch_get?{}'.format(urlencode(params, doseq=True)))

        res = self._get(url, with_tenant_token=True)
        data = res.get('data', {})
        rooms = data.get('rooms', [])
        room_list = [make_datatype(Room, i) for i in rooms]

        return room_list

    def batch_get_room_freebusy(self, room_ids, time_min, time_max):
        """会议室忙闲查询

        :type self: OpenLark
        :param room_ids: 用于查询指定会议室的ID列表
        :type room_ids: list[str]
        :param time_min: 查询会议室忙闲的起始时间
        :type time_min: datetime.datetime
        :param time_max: 查询会议室忙闲的结束时间
        :type time_max: datetime.datetime
        :return: 查询会议室忙闲的起始时间(与请求参数完全相同), 查询会议室忙闲的结束时间(与请求参数完全相同), Dict['会议室ID', List[忙碌时间]]
        :rtype: (datetime.datetime, datetime.datetime, dict[str, list[RoomFreeBusy]])

        https://open.feishu.cn/document/ukTMukTMukTM/uIDOyUjLygjM14iM4ITN
        """
        tz = TimeZoneChina()
        params = {
            'room_ids': room_ids,
            'time_min': datetime_format_rfc3339(time_min, tz),
            'time_max': datetime_format_rfc3339(time_max, tz)
        }

        url = self._gen_request_url(
            '/open-apis/meeting_room/freebusy/batch_get?{}'.format(urlencode(params, doseq=True)))

        res = self._get(url, with_tenant_token=True)
        data = res.get('data', {})
        time_min = data.get('time_min')
        time_max = data.get('time_max')
        if time_min:
            time_min = parser.parse(time_min)
        if time_max:
            time_max = parser.parse(time_max)

        return time_min, time_max, {
            k: [RoomFreeBusy(
                start_time=parser.parse(i.get('start_time')),
                end_time=parser.parse(i.get('end_time')),
                uid=i.get('uid'),
                original_time=i.get('original_time'),
                organizer_info=make_datatype(SimpleUser, i.get('organizer_info'))
            ) for i in v]
            for k, v in data.get('free_busy', {}).items()}

    def reply_meeting(self, room_id, uid, original_time, status):
        """回复会议室日程实例

        :type self: OpenLark
        :param room_id: 会议室的 ID
        :type room_id: str
        :param uid: 会议室的日程 ID
        :type uid: str
        :param original_time: 日程实例原始时间，非重复日程必为0。重复日程若为0则表示回复其所有实例，否则表示回复单个实例。
        :type original_time: int
        :param status: 回复状态，NOT_CHECK_IN 表示未签到，ENDED_BEFORE_DUE 表示提前结束
        :type status: MeetingReplyStatus
        :return: 查询会议室忙闲的起始时间(与请求参数完全相同), 查询会议室忙闲的结束时间(与请求参数完全相同), Dict['会议室ID', List[忙碌时间]]
        :rtype: (datetime.datetime, datetime.datetime, dict[str, list[RoomFreeBusy]])

        https://open.feishu.cn/document/ukTMukTMukTM/uIDOyUjLygjM14iM4ITN
        """
        body = {
            'room_id': room_id,
            'uid': uid,
            'original_time': original_time,
            'status': converter_enum(status),
        }
        url = self._gen_request_url('/open-apis/meeting_room/instance/reply')

        self._post(url, body=body, with_tenant_token=True)
