#!/usr/bin/python
# -*- coding: utf-8 -*-

# --------------------------------------------------------------------------- #
#                                                                             #
#    Plugin for iSida Jabber Bot                                              #
#    Copyright (C) diSabler <dsy@dsy.name>                                    #
#    Modified by: Fixed bash.org.ru & ibash.org.ru                           #
#                                                                             #
#    This program is free software: you can redistribute it and/or modify     #
#    it under the terms of the GNU General Public License as published by     #
#    the Free Software Foundation, either version 3 of the License, or        #
#    (at your option) any later version.                                      #
#                                                                             #
#    This program is distributed in the hope that it will be useful,          #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of           #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
#    GNU General Public License for more details.                             #
#                                                                             #
#    You should have received a copy of the GNU General Public License        #
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
#                                                                             #
# --------------------------------------------------------------------------- #

import re
import urllib.parse
import random
import json
import html

# Правильный Punycode для башорг.рф
BASH_BASE = 'https://xn--80abh7bk0c.xn--p1ai'

def clean_quote_text(text):
    """Очищает текст цитаты от HTML-сущностей и мусора"""
    if not text:
        return ''
    text = html.unescape(text)          # &lt; -> <
    text = re.sub(r'<[^>]+>', '', text) # удаляем HTML-теги
    text = re.sub(r'\s+', ' ', text)    # убираем лишние пробелы
    return text.strip()

def bash_org_ru(type, jid, nick, text):
    """Парсинг башорг.рф"""
    try:
        text = text.strip()
        if not text:
            url = BASH_BASE + '/random'
        elif re.match(r'^\d+$', text):
            url = BASH_BASE + '/quote/%s' % text
        else:
            url = BASH_BASE + '/?text=%s' % urllib.parse.quote(text.encode('utf8'))

        data = load_page(url)
        if isinstance(data, bytes):
            data = data.decode('utf-8', errors='ignore')
        if not data:
            raise Exception('No data')

        articles = re.findall(r'<article class="quote".*?data-quote="(\d+)".*?>(.*?)</article>', data, re.S)
        if not articles:
            single = re.search(r'<article class="quote".*?>(.*?)</article>', data, re.S)
            if single:
                id_match = re.search(r'data-quote="(\d+)"', data, re.S)
                if id_match:
                    articles = [(id_match.group(1), single.group(1))]
            if not articles:
                raise Exception('No quotes found')

        if not text or not re.match(r'^\d+$', text):
            article_id, article_content = random.choice(articles)
        else:
            article_id, article_content = articles[0]

        body_match = re.search(r'<div class="quote__body">(.*?)</div>', article_content, re.S)
        if not body_match:
            raise Exception('Quote body not found')

        quote_text = clean_quote_text(body_match.group(1))

        date_match = re.search(r'<div class="quote__header_date">(.*?)</div>', article_content, re.S)
        quote_date = clean_quote_text(date_match.group(1)) if date_match else ''

        rating_match = re.search(r'<div class="quote__total"[^>]*>(.*?)</div>', article_content, re.S)
        rating = clean_quote_text(rating_match.group(1)) if rating_match else ''

        msg = quote_text
        if quote_date:
            msg += '\n%s' % quote_date
        if rating:
            msg += ' | Рейтинг: %s' % rating

        send_msg(type, jid, nick, msg)

    except Exception as e:
        send_msg(type, jid, nick, L('Quote not found!', '%s/%s' % (jid, nick)))


def ibash_org_ru(type, jid, nick, text):
    """Парсинг ibash.org.ru"""
    try:
        text = text.strip()

        if not text:
            url = 'http://ibash.org.ru/random'
        elif re.match(r'^\d+$', text):
            url = 'http://ibash.org.ru/quote.php?id=%s' % text
        else:
            url = 'http://ibash.org.ru/?search=%s' % urllib.parse.quote(text.encode('utf8'))

        data = load_page(url)
        if isinstance(data, bytes):
            data = data.decode('utf-8', errors='ignore')
        if not data:
            raise Exception('No data')

        # Проверка на 404
        if '404 Not Found' in data or 'An Error Occurred' in data:
            if text and re.match(r'^\d+$', text):
                send_msg(type, jid, nick, L('Quote #%s not found (404).', '%s/%s' % (jid, nick)) % text)
            else:
                send_msg(type, jid, nick, L('Quote not found!', '%s/%s' % (jid, nick)))
            return

        quote_text = None

        # СПОСОБ 1: whitespace-pre-wrap (основной)
        pattern = r'<div class="whitespace-pre-wrap[^"]*"[^>]*>(.*?)</div>'
        matches = re.findall(pattern, data, re.S)
        for m in matches:
            q_text = clean_quote_text(m)
            if q_text and len(q_text) > 3:
                quote_text = q_text
                break

        # СПОСОБ 2: JSON-LD (запасной)
        if not quote_text:
            json_blocks = re.findall(r'<script type="application/ld\+json">(.*?)</script>', data, re.S)
            for block in json_blocks:
                try:
                    json_data = json.loads(block)
                    if isinstance(json_data, dict):
                        if 'articleBody' in json_data:
                            quote_text = json_data['articleBody']
                            quote_text = quote_text.encode('utf-8').decode('unicode-escape')
                            quote_text = clean_quote_text(quote_text)
                            break
                        if '@graph' in json_data:
                            for item in json_data['@graph']:
                                if item.get('@type') == 'Article' and 'articleBody' in item:
                                    quote_text = item['articleBody']
                                    quote_text = quote_text.encode('utf-8').decode('unicode-escape')
                                    quote_text = clean_quote_text(quote_text)
                                    break
                            if quote_text:
                                break
                except:
                    pass

        # СПОСОБ 3: border блоки (для random/search)
        if not quote_text:
            pattern = r'<div class="border border-gray-300 p-3 mb-4 bg-white rounded-sm shadow-sm"[^>]*data-controller="vote">(.*?)</div>\s*</div>'
            blocks = re.findall(pattern, data, re.S)
            quotes = []
            for block in blocks:
                text_match = re.search(r'<div class="whitespace-pre-wrap[^"]*"[^>]*>(.*?)</div>', block, re.S)
                if text_match:
                    q_text = clean_quote_text(text_match.group(1))
                    if q_text:
                        quotes.append(q_text)
            if quotes:
                if not text or not re.match(r'^\d+$', text):
                    quote_text = random.choice(quotes)
                else:
                    quote_text = quotes[0]

        if not quote_text:
            raise Exception('No quotes found')

        send_msg(type, jid, nick, quote_text)

    except Exception as e:
        send_msg(type, jid, nick, L('Quote not found!', '%s/%s' % (jid, nick)))


global execute

execute = [
    (3, 'bash', bash_org_ru, 2, 'Quote from башорг.рф\nbash [number|search]'),
    (3, 'ibash', ibash_org_ru, 2, 'Quote from ibash.org.ru\nibash [number|search]'),
]
