from flask import Blueprint, request, jsonify, Response
from flasgger import swag_from
from app.services.komiku_scraper import KomikuScraper
from app.middleware.ip_whitelist import ip_whitelist_required
from app.utils.rate_limiter import rate_limit_decorator
import cloudscraper
import random
import logging
from urllib.parse import quote
from datetime import datetime  # <-- TAMBAHKAN INI


logger = logging.getLogger(__name__)

comic_bp = Blueprint('comic', __name__, url_prefix='/api/comic')

# Scraper instance
scraper = KomikuScraper()

# User agents untuk proxy
USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
]


# ==================== CACHE ====================
# TAMBAHKAN INI
cache = {}
cache_timestamp = {}

def get_cache(key, ttl=300):
    """Get data from cache if not expired"""
    if key in cache and key in cache_timestamp:
        if (datetime.now() - cache_timestamp[key]).seconds < ttl:
            return cache[key]
    return None

def set_cache(key, data):
    """Set data to cache"""
    cache[key] = data
    cache_timestamp[key] = datetime.now()


# ==================== IMAGE PROXY ====================

@comic_bp.route('/proxy', methods=['GET'])
# Hanya rate_limit, tidak perlu ip_whitelist_required karena sudah ditangani rate_limit
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Proxy image to avoid CORS',
    'description': 'Mengambil gambar dari Komiku dan melewatkannya melalui proxy untuk menghindari CORS',
    'parameters': [
        {
            'name': 'url',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': 'URL gambar yang akan di-proxy',
            'example': 'https://img.komiku.org/wp-content/uploads/2024/01/sample.jpg'
        }
    ],
    'responses': {
        200: {
            'description': 'Gambar berhasil diambil',
            'content': {
                'image/*': {
                    'schema': {
                        'type': 'string',
                        'format': 'binary'
                    }
                }
            }
        },
        400: {'description': 'Missing url parameter'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'},
        500: {'description': 'Server error'}
    }
})
def proxy_image():
    """Proxy image to avoid CORS and blocking"""
    url = request.args.get('url')
    if not url:
        return jsonify({'error': 'Missing url parameter'}), 400
    
    try:
        proxy_scraper = cloudscraper.create_scraper(
            browser={
                'browser': 'chrome',
                'platform': 'windows',
                'desktop': True
            }
        )
        
        proxy_scraper.headers.update({
            'Referer': 'https://komiku.org/',
            'User-Agent': random.choice(USER_AGENTS)
        })
        
        response = proxy_scraper.get(url, timeout=30)
        
        if response.status_code == 200:
            return Response(
                response.content,
                status=200,
                headers={
                    'Content-Type': response.headers.get('Content-Type', 'image/jpeg'),
                    'Cache-Control': 'public, max-age=86400',
                    'Access-Control-Allow-Origin': '*',
                }
            )
        else:
            return jsonify({'error': f'Failed to fetch image: {response.status_code}'}), response.status_code
            
    except Exception as e:
        return jsonify({'error': str(e)}), 500


# ==================== COMIC ENDPOINTS ====================

@comic_bp.route('/pustaka', methods=['GET'])
@rate_limit_decorator  # Hanya rate_limit, whitelist IP mendapatkan unlimited
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get comics from pustaka',
    'description': 'Mengambil daftar komik dari pustaka Komiku',
    'parameters': [
        {
            'name': 'tipe',
            'in': 'query',
            'type': 'string',
            'enum': ['manga', 'manhwa', 'manhua'],
            'default': 'manga',
            'description': 'Tipe komik yang ingin diambil'
        },
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': 'Nomor halaman'
        },
        {
            'name': 'orderby',
            'in': 'query',
            'type': 'string',
            'enum': ['modified', 'date', 'meta_value_num', 'rand'],
            'description': 'Urutan hasil'
        },
        {
            'name': 'sorttime',
            'in': 'query',
            'type': 'string',
            'enum': ['daily', 'weekly', 'all'],
            'description': 'Filter berdasarkan waktu'
        }
    ],
    'responses': {
        200: {
            'description': 'Berhasil',
            'schema': {
                'type': 'object',
                'properties': {
                    'success': {'type': 'boolean'},
                    'message': {'type': 'string'},
                    'tipe': {'type': 'string'},
                    'page': {'type': 'integer'},
                    'has_next': {'type': 'boolean'},
                    'total': {'type': 'integer'},
                    'data': {'type': 'array'},
                    'rate_limit': {
                        'type': 'object',
                        'properties': {
                            'limit': {'oneOf': [{'type': 'string'}, {'type': 'integer'}]},
                            'remaining': {'oneOf': [{'type': 'string'}, {'type': 'integer'}]},
                            'is_whitelisted': {'type': 'boolean'},
                            'message': {'type': 'string'}
                        }
                    }
                }
            }
        },
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'},
        500: {'description': 'Server error'}
    }
})
def get_pustaka():
    """Get comics from pustaka"""
    try:
        tipe = request.args.get('tipe', 'manga')
        page = request.args.get('page', 1, type=int)
        orderby = request.args.get('orderby')
        sorttime = request.args.get('sorttime')
        
        result = scraper.get_pustaka(tipe, page, orderby, sorttime)
        
        if result['status']:
            return {
                'success': True,
                'message': result['message'],
                'tipe': result['tipe'],
                'page': result['page'],
                'has_next': result.get('has_next', False),
                'total': result['total'],
                'data': result['data']
            }, 200
        else:
            return {
                'success': False,
                'error': result.get('message', 'Failed')
            }, 500
        
    except Exception as e:
        logger.error(f"[PUSTAKA] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/search', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Search comics',
    'description': 'Mencari komik berdasarkan judul',
    'parameters': [
        {
            'name': 'q',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': 'Kata kunci pencarian',
            'example': 'one piece'
        }
    ],
    'responses': {
        200: {
            'description': 'Berhasil',
            'schema': {
                'type': 'object',
                'properties': {
                    'success': {'type': 'boolean'},
                    'creator': {'type': 'string'},
                    'message': {'type': 'string'},
                    'q': {'type': 'string'},
                    'url': {'type': 'string'},
                    'total': {'type': 'integer'},
                    'data': {'type': 'array'},
                    'rate_limit': {'type': 'object'}
                }
            }
        },
        400: {'description': 'Missing query parameter'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def search_comics():
    """Search comics by keyword - SAMA PERSIS KAYAK CODE ASLI"""
    try:
        query = request.args.get('q', '')
        if not query:
            return jsonify({'success': False, 'error': 'Query parameter "q" is required'}), 400
        
        cache_key = f"komiku_search:{query}"
        cached_data = get_cache(cache_key, 300)
        if cached_data:
            return jsonify(cached_data)
        
        result = scraper.search_comics(query)
        
        # Response SAMA PERSIS kayak code asli
        response_data = {
            'success': result['status'],
            'creator': result.get('creator', 'Zyann'),
            'message': result.get('message', ''),
            'q': query,
            'url': result.get('url', ''),
            'total': result.get('total', 0),
            'data': result.get('data', [])
        }
        
        set_cache(cache_key, response_data)
        return jsonify(response_data), 200 if result['status'] else 404
        
    except Exception as e:
        logger.error(f"[SEARCH] Error: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@comic_bp.route('/genres', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get all genres',
    'description': 'Mengambil daftar semua genre yang tersedia di Komiku',
    'responses': {
        200: {
            'description': 'Berhasil',
            'schema': {
                'type': 'object',
                'properties': {
                    'success': {'type': 'boolean'},
                    'data': {'type': 'array'},
                    'total': {'type': 'integer'},
                    'rate_limit': {'type': 'object'}
                }
            }
        },
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_genres():
    """Get all genres"""
    try:
        genres = scraper.get_genres()
        return {
            'success': True,
            'data': genres,
            'total': len(genres)
        }, 200
        
    except Exception as e:
        logger.error(f"[GENRES] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/genre/<string:genre_slug>', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get comics by genre',
    'description': 'Mengambil daftar komik berdasarkan genre tertentu',
    'parameters': [
        {
            'name': 'genre_slug',
            'in': 'path',
            'type': 'string',
            'required': True,
            'description': 'Slug genre',
            'example': 'action'
        },
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': 'Nomor halaman'
        },
        {
            'name': 'orderby',
            'in': 'query',
            'type': 'string',
            'enum': ['modified', 'date', 'meta_value_num', 'rand'],
            'default': 'modified',
            'description': 'Urutan hasil'
        },
        {
            'name': 'tipe',
            'in': 'query',
            'type': 'string',
            'enum': ['manga', 'manhwa', 'manhua'],
            'description': 'Filter berdasarkan tipe'
        }
    ],
    'responses': {
        200: {'description': 'Berhasil'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_genre_comics(genre_slug):
    """Get comics by genre"""
    try:
        page = request.args.get('page', 1, type=int)
        orderby = request.args.get('orderby', 'modified')
        tipe = request.args.get('tipe')
        
        result = scraper.get_genre_comics(genre_slug, page, orderby, tipe)
        
        if result['status']:
            return {
                'success': True,
                'message': result['message'],
                'genre': genre_slug,
                'page': page,
                'has_next': result.get('has_next', False),
                'total': result['total'],
                'data': result['data']
            }, 200
        else:
            return {
                'success': False,
                'error': result.get('message', 'Failed')
            }, 500
        
    except Exception as e:
        logger.error(f"[GENRE] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/detail/<string:slug>', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get comic detail by slug',
    'description': 'Mengambil informasi detail dari sebuah komik berdasarkan slug',
    'parameters': [
        {
            'name': 'slug',
            'in': 'path',
            'type': 'string',
            'required': True,
            'description': 'Slug komik',
            'example': 'one-piece'
        }
    ],
    'responses': {
        200: {'description': 'Berhasil'},
        404: {'description': 'Comic not found'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_comic_detail(slug):
    """Get comic detail by slug"""
    try:
        result = scraper.get_manga_detail(slug)
        
        if result['status']:
            return {
                'success': True,
                'message': result['message'],
                'data': result['data']
            }, 200
        else:
            return {'success': False, 'error': 'Comic not found'}, 404
        
    except Exception as e:
        logger.error(f"[DETAIL] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/chapter', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get chapter data',
    'description': 'Mengambil data chapter termasuk daftar gambar',
    'parameters': [
        {
            'name': 'slug',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': 'Slug chapter',
            'example': 'one-piece-chapter-1000'
        }
    ],
    'responses': {
        200: {'description': 'Berhasil'},
        400: {'description': 'Missing slug parameter'},
        404: {'description': 'Chapter not found'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_chapter():
    """Get chapter data with images"""
    try:
        slug = request.args.get('slug')
        if not slug:
            return {'success': False, 'error': 'Slug parameter is required'}, 400
        
        result = scraper.get_chapter_data(slug)
        
        if result and result.get('images'):
            return result, 200
        else:
            return {'success': False, 'error': 'Chapter not found'}, 404
        
    except Exception as e:
        logger.error(f"[CHAPTER] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/ranking/<string:period>', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get ranking',
    'description': 'Mengambil data ranking komik berdasarkan periode',
    'parameters': [
        {
            'name': 'period',
            'in': 'path',
            'type': 'string',
            'required': True,
            'enum': ['mingguan', 'harian', 'total'],
            'description': 'Periode ranking'
        }
    ],
    'responses': {
        200: {'description': 'Berhasil'},
        400: {'description': 'Invalid period'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_ranking(period):
    """Get ranking by period"""
    try:
        if period not in ['mingguan', 'harian', 'total']:
            return {'success': False, 'error': 'Invalid period. Use: mingguan, harian, total'}, 400
        
        results = scraper.get_ranking(period)
        
        return {
            'success': True,
            'data': results,
            'period': period,
            'total': len(results)
        }, 200
        
    except Exception as e:
        logger.error(f"[RANKING] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/populer', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get popular comics',
    'description': 'Mengambil daftar komik populer dari Komiku',
    'parameters': [
        {
            'name': 'tipe',
            'in': 'query',
            'type': 'string',
            'enum': ['semua', 'Manga', 'Manhwa', 'Manhua'],
            'default': 'semua',
            'description': 'Filter berdasarkan tipe'
        }
    ],
    'responses': {
        200: {'description': 'Berhasil'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_populer():
    """Get popular comics"""
    try:
        tipe = request.args.get('tipe', 'semua')
        results = scraper.get_populer(tipe)
        
        return {
            'success': True,
            'data': results,
            'tipe': tipe,
            'total': len(results)
        }, 200
        
    except Exception as e:
        logger.error(f"[POPULER] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/terbaru', methods=['GET'])
@rate_limit_decorator
@swag_from({
    'tags': ['Komiku'],
    'summary': 'Get latest comics',
    'description': 'Mengambil daftar komik terbaru dari Komiku',
    'responses': {
        200: {'description': 'Berhasil'},
        429: {'description': 'Rate limit exceeded (hanya untuk IP non-whitelist)'}
    }
})
def get_terbaru():
    """Get latest comics"""
    try:
        results = scraper.get_terbaru()
        
        return {
            'success': True,
            'data': results,
            'total': len(results)
        }, 200
        
    except Exception as e:
        logger.error(f"[TERBARU] Error: {e}")
        return {'success': False, 'error': str(e)}, 500


@comic_bp.route('/health', methods=['GET'])
@swag_from({
    'tags': ['System'],
    'summary': 'Health check',
    'description': 'Memeriksa status kesehatan API',
    'responses': {
        200: {
            'description': 'API sehat',
            'schema': {
                'type': 'object',
                'properties': {
                    'success': {'type': 'boolean'},
                    'status': {'type': 'string'},
                    'message': {'type': 'string'},
                    'base_url': {'type': 'string'}
                }
            }
        }
    }
})
def health_check():
    """Health check endpoint"""
    return {
        'success': True,
        'status': 'healthy',
        'message': 'Komiku API is running',
        'base_url': scraper.base_url
    }, 200