# SPDX-License-Identifier: AGPL-3.0-or-later
"""Dailymotion (Videos)

"""

from typing import Set
from datetime import datetime, timedelta
from urllib.parse import urlencode
import time
import babel

from searx.exceptions import SearxEngineAPIException
from searx.network import raise_for_httperror
from searx.utils import html_to_text

# about
about = {
    "website": 'https://www.dailymotion.com',
    "wikidata_id": 'Q769222',
    "official_api_documentation": 'https://www.dailymotion.com/developer',
    "use_official_api": True,
    "require_api_key": False,
    "results": 'JSON',
}

# engine dependent config
categories = ['videos']
paging = True
number_of_results = 10

time_range_support = True
time_delta_dict = {
    "day": timedelta(days=1),
    "week": timedelta(days=7),
    "month": timedelta(days=31),
    "year": timedelta(days=365),
}

safesearch = True
safesearch_params = {2: '&is_created_for_kids=true', 1: '&is_created_for_kids=true', 0: ''}

# search-url
# - https://developers.dailymotion.com/tools/
# - https://www.dailymotion.com/doc/api/obj-video.html

result_fields = [
    'allow_embed',
    'description',
    'title',
    'created_time',
    'duration',
    'url',
    'thumbnail_360_url',
    'id',
]
search_url = (
    'https://api.dailymotion.com/videos?'
    'fields={fields}&password_protected={password_protected}&private={private}&sort={sort}&limit={limit}'
).format(
    fields=','.join(result_fields),
    password_protected='false',
    private='false',
    sort='relevance',
    limit=number_of_results,
)
iframe_src = "https://www.dailymotion.com/embed/video/{video_id}"

# The request query filters by 'languages' & 'country', therefore instead of
# fetching only languages we need to fetch locales.
supported_languages_url = 'https://api.dailymotion.com/locales'
supported_languages_iso639: Set[str] = set()


def init(_engine_settings):
    global supported_languages_iso639
    supported_languages_iso639 = set([language.split('_')[0] for language in supported_languages])


def request(query, params):

    if not query:
        return False

    language = params['language']
    if language == 'all':
        language = 'en-US'
    locale = babel.Locale.parse(language, sep='-')

    language_iso639 = locale.language
    if locale.language not in supported_languages_iso639:
        language_iso639 = 'en'

    query_args = {
        'search': query,
        'languages': language_iso639,
        'page': params['pageno'],
    }

    if locale.territory:
        localization = locale.language + '_' + locale.territory
        if localization in supported_languages:
            query_args['country'] = locale.territory

    time_delta = time_delta_dict.get(params["time_range"])
    if time_delta:
        created_after = datetime.now() - time_delta
        query_args['created_after'] = datetime.timestamp(created_after)

    query_str = urlencode(query_args)
    params['url'] = search_url + '&' + query_str + safesearch_params.get(params['safesearch'], '')
    params['raise_for_httperror'] = False

    return params


# get response from search-request
def response(resp):
    results = []

    search_res = resp.json()

    # check for an API error
    if 'error' in search_res:
        raise SearxEngineAPIException(search_res['error'].get('message'))

    raise_for_httperror(resp)

    # parse results
    for res in search_res.get('list', []):

        title = res['title']
        url = res['url']

        content = html_to_text(res['description'])
        if len(content) > 300:
            content = content[:300] + '...'

        publishedDate = datetime.fromtimestamp(res['created_time'], None)

        length = time.gmtime(res.get('duration'))
        if length.tm_hour:
            length = time.strftime("%H:%M:%S", length)
        else:
            length = time.strftime("%M:%S", length)

        thumbnail = res['thumbnail_360_url']
        thumbnail = thumbnail.replace("http://", "https://")

        item = {
            'template': 'videos.html',
            'url': url,
            'title': title,
            'content': content,
            'publishedDate': publishedDate,
            'length': length,
            'thumbnail': thumbnail,
        }

        # HINT: no mater what the value is, without API token videos can't shown
        # embedded
        if res['allow_embed']:
            item['iframe_src'] = iframe_src.format(video_id=res['id'])

        results.append(item)

    # return results
    return results


# get supported languages from their site
def _fetch_supported_languages(resp):
    response_json = resp.json()
    return [item['locale'] for item in response_json['list']]