# -*- coding: utf-8 -*-
"""
수인약품 도매상 API - Flask Blueprint

핵심 로직은 wholesale 패키지에서 가져옴
이 파일은 Flask 웹 API 연동만 담당
"""

import time
import logging

from flask import Blueprint, jsonify, request as flask_request

# wholesale 패키지 경로 설정
import wholesale_path

# wholesale 패키지에서 핵심 클래스 가져오기
from wholesale import SooinSession

logger = logging.getLogger(__name__)

# Blueprint 생성
sooin_bp = Blueprint('sooin', __name__, url_prefix='/api/sooin')


# ========== 세션 관리 ==========

_sooin_session = None

def get_sooin_session():
    global _sooin_session
    if _sooin_session is None:
        _sooin_session = SooinSession()
    return _sooin_session


def search_sooin_stock(keyword: str, search_type: str = 'kd_code'):
    """수인약품 재고 검색 (동기, 빠름)"""
    try:
        session = get_sooin_session()
        result = session.search_products(keyword)
        
        if result.get('success'):
            return {
                'success': True,
                'keyword': keyword,
                'search_type': search_type,
                'count': result['total'],
                'items': result['items']
            }
        else:
            return result
        
    except Exception as e:
        logger.error(f"수인약품 검색 오류: {e}")
        return {'success': False, 'error': 'SEARCH_ERROR', 'message': str(e)}


# ========== Flask API Routes ==========

@sooin_bp.route('/stock', methods=['GET'])
def api_sooin_stock():
    """
    수인약품 재고 조회 API
    
    GET /api/sooin/stock?kd_code=073100220
    GET /api/sooin/stock?keyword=코자정&type=name
    """
    kd_code = flask_request.args.get('kd_code', '').strip()
    keyword = flask_request.args.get('keyword', '').strip()
    search_type = flask_request.args.get('type', 'kd_code').strip()
    
    search_term = kd_code or keyword
    if kd_code:
        search_type = 'kd_code'
    
    if not search_term:
        return jsonify({
            'success': False,
            'error': 'MISSING_PARAM',
            'message': 'kd_code 또는 keyword 파라미터가 필요합니다'
        }), 400
    
    try:
        result = search_sooin_stock(search_term, search_type)
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 API 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'API_ERROR',
            'message': str(e)
        }), 500


@sooin_bp.route('/session-status', methods=['GET'])
def api_session_status():
    """세션 상태 확인"""
    session = get_sooin_session()
    return jsonify({
        'logged_in': session._logged_in,
        'last_login': session._last_login,
        'session_age_sec': int(time.time() - session._last_login) if session._last_login else None
    })


@sooin_bp.route('/balance', methods=['GET'])
def api_sooin_balance():
    """
    수인약품 잔고(미수금) 조회 API
    
    GET /api/sooin/balance
    
    Returns:
        {
            "success": true,
            "balance": 14293001,        // 현재 잔고 (누계합)
            "prev_balance": 10592762,   // 전일잔액
            "monthly_sales": 3700239,   // 월 매출
            "yearly_sales": 34380314    // 연 누계 매출
        }
    """
    try:
        session = get_sooin_session()
        result = session.get_balance()
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 잔고 조회 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'BALANCE_ERROR',
            'message': str(e),
            'balance': 0
        }), 500


@sooin_bp.route('/monthly-sales', methods=['GET'])
def api_sooin_monthly_sales():
    """
    수인약품 월간 매출 조회 API
    
    GET /api/sooin/monthly-sales?year=2026&month=3
    
    Returns:
        {
            "success": true,
            "total_amount": 3700239,      // 월간 매출 합계
            "total_paid": 0,              // 월간 입금 합계
            "ending_balance": 14293001,   // 월말 잔액
            "opening_balance": 10592762,  // 전일(기초) 잔액
            "from_date": "2026-03-01",
            "to_date": "2026-03-31"
        }
    """
    from datetime import datetime
    
    year = flask_request.args.get('year', type=int)
    month = flask_request.args.get('month', type=int)
    
    # 기본값: 현재 월
    if not year or not month:
        now = datetime.now()
        year = year or now.year
        month = month or now.month
    
    try:
        session = get_sooin_session()
        if hasattr(session, 'get_monthly_sales'):
            result = session.get_monthly_sales(year, month)
            return jsonify(result)
        else:
            return jsonify({
                'success': False,
                'error': 'NOT_IMPLEMENTED',
                'message': '수인약품 월간 매출 조회 미구현'
            }), 501
    except Exception as e:
        logger.error(f"수인약품 월간 매출 조회 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'MONTHLY_SALES_ERROR',
            'message': str(e)
        }), 500


@sooin_bp.route('/cart', methods=['GET'])
def api_sooin_cart():
    """장바구니 조회 API"""
    try:
        session = get_sooin_session()
        result = session.get_cart()
        return jsonify(result)
    except Exception as e:
        return jsonify({'success': False, 'error': str(e), 'items': []}), 500


@sooin_bp.route('/cart/clear', methods=['POST'])
def api_sooin_cart_clear():
    """장바구니 비우기 API"""
    try:
        session = get_sooin_session()
        result = session.clear_cart()
        return jsonify(result)
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@sooin_bp.route('/cart/cancel', methods=['POST'])
def api_sooin_cart_cancel():
    """
    장바구니 항목 취소 API
    
    POST /api/sooin/cart/cancel
    { "row_index": 0 }
    또는
    { "internal_code": "32495" }
    """
    data = flask_request.get_json() or {}
    row_index = data.get('row_index')
    internal_code = data.get('internal_code')
    
    if row_index is None and not internal_code:
        return jsonify({
            'success': False,
            'error': 'MISSING_PARAM',
            'message': 'row_index 또는 internal_code가 필요합니다'
        }), 400
    
    try:
        session = get_sooin_session()
        result = session.cancel_item(row_index=row_index, product_code=internal_code)
        return jsonify(result)
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@sooin_bp.route('/cart/restore', methods=['POST'])
def api_sooin_cart_restore():
    """
    취소된 항목 복원 API
    
    POST /api/sooin/cart/restore
    { "row_index": 0 }
    """
    data = flask_request.get_json() or {}
    row_index = data.get('row_index')
    internal_code = data.get('internal_code')
    
    try:
        session = get_sooin_session()
        result = session.restore_item(row_index=row_index, product_code=internal_code)
        return jsonify(result)
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@sooin_bp.route('/order', methods=['POST'])
def api_sooin_order():
    """
    수인약품 주문 API (장바구니 추가)
    
    POST /api/sooin/order
    {
        "kd_code": "073100220",
        "quantity": 1,
        "specification": "30T",
        "check_stock": true
    }
    """
    data = flask_request.get_json()
    
    if not data:
        return jsonify({'success': False, 'error': 'NO_DATA'}), 400
    
    kd_code = data.get('kd_code', '').strip()
    quantity = data.get('quantity', 1)
    specification = data.get('specification')
    check_stock = data.get('check_stock', True)
    
    if not kd_code:
        return jsonify({
            'success': False,
            'error': 'MISSING_PARAM',
            'message': 'kd_code가 필요합니다'
        }), 400
    
    try:
        session = get_sooin_session()
        result = session.quick_order(
            kd_code=kd_code,
            quantity=quantity,
            spec=specification,
            check_stock=check_stock
        )
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 주문 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'ORDER_ERROR',
            'message': str(e)
        }), 500


@sooin_bp.route('/confirm', methods=['POST'])
def api_sooin_confirm():
    """주문 확정 API"""
    data = flask_request.get_json() or {}
    memo = data.get('memo', '')
    
    try:
        session = get_sooin_session()
        result = session.submit_order(memo)
        return jsonify(result)
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@sooin_bp.route('/full-order', methods=['POST'])
def api_sooin_full_order():
    """
    전체 주문 API (검색 → 장바구니 → 확정)
    
    POST /api/sooin/full-order
    {
        "kd_code": "073100220",
        "quantity": 1,
        "specification": "30T",
        "auto_confirm": true,
        "memo": "자동주문"
    }
    """
    data = flask_request.get_json()
    
    if not data or not data.get('kd_code'):
        return jsonify({'success': False, 'error': 'kd_code required'}), 400
    
    try:
        session = get_sooin_session()
        
        # 장바구니에 담기
        cart_result = session.quick_order(
            kd_code=data['kd_code'],
            quantity=data.get('quantity', 1),
            spec=data.get('specification'),
            check_stock=data.get('check_stock', True)
        )
        
        if not cart_result.get('success'):
            return jsonify(cart_result)
        
        if not data.get('auto_confirm', True):
            return jsonify(cart_result)
        
        # 주문 확정
        confirm_result = session.submit_order(data.get('memo', ''))
        
        if confirm_result.get('success'):
            return jsonify({
                'success': True,
                'message': f"{cart_result['product']['name']} {cart_result['quantity']}개 주문 완료",
                'product': cart_result['product'],
                'quantity': cart_result['quantity'],
                'confirmed': True
            })
        else:
            return jsonify({
                'success': False,
                'error': confirm_result.get('error', 'CONFIRM_FAILED'),
                'message': f"장바구니 담기 성공, 주문 확정 실패",
                'product': cart_result['product'],
                'cart_added': True
            })
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@sooin_bp.route('/order-batch', methods=['POST'])
def api_sooin_order_batch():
    """수인약품 일괄 주문 API"""
    data = flask_request.get_json()
    
    if not data or not data.get('items'):
        return jsonify({'success': False, 'error': 'NO_ITEMS'}), 400
    
    items = data.get('items', [])
    check_stock = data.get('check_stock', True)
    
    session = get_sooin_session()
    results = []
    success_count = 0
    failed_count = 0
    
    for item in items:
        kd_code = item.get('kd_code', '').strip()
        quantity = item.get('quantity', 1)
        specification = item.get('specification')
        
        if not kd_code:
            results.append({
                'kd_code': kd_code,
                'success': False,
                'error': 'MISSING_KD_CODE'
            })
            failed_count += 1
            continue
        
        try:
            result = session.quick_order(
                kd_code=kd_code,
                quantity=quantity,
                spec=specification,
                check_stock=check_stock
            )
            result['kd_code'] = kd_code
            result['requested_qty'] = quantity
            results.append(result)
            
            if result.get('success'):
                success_count += 1
            else:
                failed_count += 1
                
        except Exception as e:
            results.append({
                'kd_code': kd_code,
                'success': False,
                'error': 'EXCEPTION',
                'message': str(e)
            })
            failed_count += 1
    
    return jsonify({
        'success': True,
        'total': len(items),
        'success_count': success_count,
        'failed_count': failed_count,
        'results': results
    })


# ========== 주문 조회 API ==========

@sooin_bp.route('/orders', methods=['GET'])
def api_sooin_orders():
    """
    수인약품 주문 목록 조회 API
    
    GET /api/sooin/orders?start_date=2026-03-01&end_date=2026-03-07
    
    파라미터:
        start_date: 시작일 (YYYY-MM-DD), 기본값: 오늘
        end_date: 종료일 (YYYY-MM-DD), 기본값: 오늘
    
    Returns:
        {
            "success": true,
            "orders": [
                {
                    "order_num": "202603095091177",
                    "order_date": "2026-03-09",
                    "order_time": "14:30:25",
                    "total_amount": 125000,
                    "item_count": 5,
                    "status": "완료"
                }
            ],
            "total_count": 10
        }
    """
    from datetime import datetime
    
    today = datetime.now().strftime("%Y-%m-%d")
    start_date = flask_request.args.get('start_date', today).strip()
    end_date = flask_request.args.get('end_date', today).strip()
    
    try:
        session = get_sooin_session()
        result = session.get_order_list(start_date, end_date)
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 주문 목록 조회 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'ORDERS_ERROR',
            'message': str(e),
            'orders': [],
            'total_count': 0
        }), 500


@sooin_bp.route('/orders/today-summary', methods=['GET'])
def api_sooin_today_summary():
    """
    수인약품 오늘 주문 집계 API
    
    GET /api/sooin/orders/today-summary
    
    Returns:
        {
            "success": true,
            "date": "2026-03-09",
            "summary": [
                {
                    "kd_code": "073100220",
                    "product_name": "코자정50mg",
                    "total_quantity": 10,
                    "total_amount": 150000,
                    "order_count": 3
                }
            ],
            "grand_total_amount": 500000,
            "grand_total_items": 25,
            "order_count": 5
        }
    """
    try:
        session = get_sooin_session()
        result = session.get_today_order_summary()
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 오늘 주문 집계 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'TODAY_SUMMARY_ERROR',
            'message': str(e),
            'summary': [],
            'grand_total_amount': 0,
            'grand_total_items': 0,
            'order_count': 0
        }), 500


@sooin_bp.route('/orders/<order_num>', methods=['GET'])
def api_sooin_order_detail(order_num):
    """
    수인약품 주문 상세 조회 API
    
    GET /api/sooin/orders/202603095091177
    
    Returns:
        {
            "success": true,
            "order_num": "202603095091177",
            "order_date": "2026-03-09",
            "items": [
                {
                    "product_code": "32495",
                    "kd_code": "073100220",
                    "product_name": "코자정50mg",
                    "spec": "30T",
                    "quantity": 2,
                    "unit_price": 15000,
                    "amount": 30000
                }
            ],
            "total_amount": 125000,
            "item_count": 5
        }
    """
    if not order_num or not order_num.isdigit():
        return jsonify({
            'success': False,
            'error': 'INVALID_ORDER_NUM',
            'message': '유효한 주문번호를 입력하세요'
        }), 400
    
    try:
        session = get_sooin_session()
        result = session.get_order_detail(order_num)
        return jsonify(result)
    except Exception as e:
        logger.error(f"수인약품 주문 상세 조회 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'ORDER_DETAIL_ERROR',
            'message': str(e),
            'order_num': order_num,
            'items': [],
            'total_amount': 0
        }), 500


@sooin_bp.route('/orders/summary-by-kd', methods=['GET'])
def api_sooin_orders_by_kd():
    """
    수인약품 주문량 KD코드별 집계 API (병렬 처리)
    
    GET /api/sooin/orders/summary-by-kd?start_date=2026-03-01&end_date=2026-03-07
    """
    import re
    from datetime import datetime
    
    today = datetime.now().strftime("%Y-%m-%d")
    start_date = flask_request.args.get('start_date', today).strip()
    end_date = flask_request.args.get('end_date', today).strip()
    
    def parse_spec(spec: str) -> int:
        """
        규격에서 박스당 단위 수 추출
        
        정량 단위 (T, 정, 캡슐, C, PTP, 포 등): 숫자 추출
        용량 단위 (g, ml, mL, mg, L 등): 1 반환 (튜브/병 단위)
        
        예시:
        - '30T' → 30 (정제 30정)
        - '100정(PTP)' → 100
        - '15g' → 1 (튜브 1개)
        - '10ml' → 1 (병 1개)
        - '500mg' → 1 (용량 표시)
        """
        if not spec:
            return 1
        
        spec_lower = spec.lower()
        
        # 용량 단위 패턴: 숫자 + g/ml/mg/l (단독 또는 끝)
        # 이 경우 튜브/병 단위이므로 1 반환
        volume_pattern = r'^\d+\s*(g|ml|mg|l)(\s|$|\)|/)'
        if re.search(volume_pattern, spec_lower):
            return 1
        
        # 정량 단위 패턴: 숫자 + T/정/캡슐/C/PTP/포
        qty_pattern = r'(\d+)\s*(t|정|캡슐?|c|ptp|포|tab|cap)'
        qty_match = re.search(qty_pattern, spec_lower)
        if qty_match:
            return int(qty_match.group(1))
        
        # 기본: 숫자만 있으면 추출하되, 용량 단위 재확인
        # 끝에 g/ml이 있으면 1 반환
        if re.search(r'\d+(g|ml)$', spec_lower):
            return 1
        
        # 그 외 숫자 추출
        match = re.search(r'(\d+)', spec)
        return int(match.group(1)) if match else 1
    
    try:
        session = get_sooin_session()
        
        # 주문 목록 조회
        orders_result = session.get_order_list(start_date, end_date)
        
        if not orders_result.get('success'):
            return jsonify({
                'success': False,
                'error': orders_result.get('error', 'ORDERS_FETCH_FAILED'),
                'by_kd_code': {}
            })
        
        orders = orders_result.get('orders', [])
        order_nums = [o.get('order_num') for o in orders if o.get('order_num')]
        
        # 순차 처리 + 캐시 (캐시 효과 극대화)
        all_details = []
        
        for order_num in order_nums:
            try:
                detail = session.get_order_detail(order_num)
                if detail.get('success'):
                    all_details.append(detail)
            except Exception as e:
                logger.warning(f"주문 상세 조회 실패: {e}")
        
        # KD코드별 집계
        kd_summary = {}
        
        for detail in all_details:
            for item in detail.get('items', []):
                kd_code = item.get('kd_code', '')
                if not kd_code:
                    continue
                
                product_name = item.get('product_name', '')
                spec = item.get('spec', '')
                quantity = item.get('quantity', 0)
                per_unit = parse_spec(spec)
                total_units = quantity * per_unit
                
                if kd_code not in kd_summary:
                    kd_summary[kd_code] = {
                        'product_name': product_name,
                        'spec': spec,
                        'boxes': 0,
                        'units': 0
                    }
                
                kd_summary[kd_code]['boxes'] += quantity
                kd_summary[kd_code]['units'] += total_units
        
        return jsonify({
            'success': True,
            'order_count': len(order_nums),
            'period': {'start': start_date, 'end': end_date},
            'by_kd_code': kd_summary,
            'total_products': len(kd_summary)
        })
        
    except Exception as e:
        logger.error(f"수인약품 KD코드별 집계 오류: {e}")
        return jsonify({
            'success': False,
            'error': 'SUMMARY_ERROR',
            'message': str(e),
            'by_kd_code': {}
        }), 500
