import frappe
import json
import os

@frappe.whitelist()
def get_tax_exempt_articles(doctype, txt, searchfield, start, page_len, filters):
    """Возвращает список налоговых статей для tax exempt assets"""
    
    # Ключевые части названий для поиска
    allowed_patterns = [
        '199.1',
        '199.4.1',
        '199.4.2', 
        '199.4.3',
        '199.4.4',
        '199.5',
        '199.7',
        '199.8',
        '199.9',
        '199.11',
        '199.14',
        '199.15',
        '199.16',
        '199.17',
        '199.18',
        '199.19',
        '199.20',
        '227.1',
        'Qanunla təsdiq olunmuş hasilatın pay bölgüsü',
        'Xüsusi iqtisadi zonalar',
        'Azərbaycan Respublikasının tərəfdar çıxdığı beynəlxalq müqavilələr'
    ]
    
    # Строим условие для поиска
    conditions = []
    for pattern in allowed_patterns:
        conditions.append(f"name LIKE '%{pattern}%'")
    
    # Добавляем поисковый текст если есть
    where_clause = f"({' OR '.join(conditions)})"
    if txt:
        where_clause += f" AND name LIKE '%{txt}%'"
    
    # Выполняем запрос
    result = frappe.db.sql(f"""
        SELECT name
        FROM `tabTax Article`
        WHERE {where_clause}
        ORDER BY name
        LIMIT {start}, {page_len}
    """)
    
    return result

@frappe.whitelist()
def get_land_tax_articles(doctype, txt, searchfield, start, page_len, filters):
    """Возвращает список налоговых статей для земельных участков"""
    
    # Ключевые части названий для поиска земельных участков
    allowed_patterns = [
        'Vergi Məcəlləsinin 207.3-cü maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.4-cü maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.5-ci maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.6-cı maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.7-ci maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.8-ci maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.9-cu maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.10-cu maddəsinə əsasən',
        'Vergi Məcəlləsinin 207.11-ci maddəsinə əsasən',
        'Vergi məcəlləsinin 207.12-ci maddəsinə əsasən',
        'Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən'
    ]
    
    # Строим условие для поиска
    conditions = []
    for pattern in allowed_patterns:
        conditions.append(f"name LIKE '%{pattern}%'")
    
    # Добавляем поисковый текст если есть
    where_clause = f"({' OR '.join(conditions)})"
    if txt:
        where_clause += f" AND name LIKE '%{txt}%'"
    
    # Выполняем запрос
    result = frappe.db.sql(f"""
        SELECT name
        FROM `tabTax Article`
        WHERE {where_clause}
        ORDER BY name
        LIMIT {start}, {page_len}
    """)
    
    return result

# ===============================
# СЕЛЬСКОХОЗЯЙСТВЕННЫЕ ЗЕМЛИ
# ===============================

@frappe.whitelist()
def calculate_gross_purchase_amount(hectare, cadastral_district_name, quality_groups, agricultural_land_purpose):
    """
    Рассчитывает Gross Purchase Amount для сельскохозяйственных земель
    Формула: hectare × балл × наценка
    """
    try:
        # Валидация входных данных
        if not hectare or not cadastral_district_name or not quality_groups or not agricultural_land_purpose:
            frappe.throw("Не все поля заполнены для расчета")
        
        # Получаем балл из JSON файла
        score = get_cadastral_score(cadastral_district_name, quality_groups)
        
        # Определяем наценку
        markup = get_markup_coefficient(agricultural_land_purpose)
        
        # Расчет по формуле
        result = float(hectare) * score * markup
        
        return {
            'gross_purchase_amount': result,
            'calculation_details': {
                'hectare': float(hectare),
                'score': score,
                'markup': markup,
                'formula': f"{hectare} × {score} × {markup} = {result}"
            }
        }
        
    except Exception as e:
        frappe.throw(f"Ошибка при расчете: {str(e)}")

def get_cadastral_score(cadastral_district_name, quality_group):
    """
    Извлекает балл из JSON файла на основе названия кадастрового района и группы качества
    """
    try:
        # Путь к JSON файлу
        json_file_path = frappe.get_app_path('jey_erp', 'data', 'cadastral_points_data.json')
        
        # Читаем JSON файл
        with open(json_file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)
        
        # Поиск соответствующего региона
        for region in data.get('cadastral_regions', []):
            if region.get('region_name') == cadastral_district_name:
                # Получаем балл для указанной группы качества
                quality_groups = region.get('quality_groups', {})
                score = quality_groups.get(quality_group)
                
                # Если балл null или не найден, возвращаем 0
                return score if score is not None else 0
        
        # Если регион не найден
        frappe.throw(f"Кадастровый район '{cadastral_district_name}' не найден в базе данных")
        
    except FileNotFoundError:
        frappe.throw("Файл с кадастровыми данными не найден. Обратитесь к администратору системы")
    except json.JSONDecodeError:
        frappe.throw("Ошибка чтения файла с кадастровыми данными")
    except Exception as e:
        frappe.throw(f"Ошибка при получении кадастрового балла: {str(e)}")

def get_markup_coefficient(agricultural_land_purpose):
    """
    Определяет коэффициент наценки на основе цели использования земли
    """
    markup_map = {
        "Əkin, dinc və çoxillik əkmələr": 0.06,
        "Biçənək, örüş və otlaqlar": 0.006  # 0.06 / 10
    }
    
    coefficient = markup_map.get(agricultural_land_purpose)
    
    if coefficient is None:
        frappe.throw(f"Неизвестный тип назначения земли: {agricultural_land_purpose}")
    
    return coefficient

# ===============================
# ПРОМЫШЛЕННЫЕ/КОММЕРЧЕСКИЕ ЗЕМЛИ
# ===============================

@frappe.whitelist()
def calculate_industrial_gross_purchase_amount(hectare, territorial_unit_name, industrial_land_purpose):
    """
    Рассчитывает Gross Purchase Amount для промышленных земель
    Формула: (площадь_в_м² ÷ 100) × балл (прогрессивная система)
    """
    try:
        # Валидация входных данных
        if not hectare or not territorial_unit_name or not industrial_land_purpose:
            frappe.throw("Не все поля заполнены для расчета")
        
        # Используем значение как есть - это квадратные метры
        area_sqm = float(hectare)
        
        # Получаем баллы из JSON файла
        score_data = get_industrial_land_scores(territorial_unit_name, industrial_land_purpose)
        
        # Рассчитываем по прогрессивной формуле
        calculation_result = calculate_industrial_land_formula(area_sqm, score_data)
        
        return {
            'gross_purchase_amount': calculation_result['total'],
            'calculation_details': calculation_result
        }
        
    except Exception as e:
        frappe.throw(f"Ошибка при расчете: {str(e)}")

def get_industrial_land_scores(territorial_unit_name, industrial_land_purpose):
    """
    Извлекает баллы из JSON файла для промышленных земель
    """
    try:
        # Путь к JSON файлу
        json_file_path = frappe.get_app_path('jey_erp', 'data', 'industrial_land_data.json')
        
        # Читаем JSON файл
        with open(json_file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)
        
        # Поиск соответствующего региона
        for region in data.get('industrial_land_regions', []):
            if region.get('settlement_name') == territorial_unit_name:
                # Получаем баллы для указанного назначения земли
                land_purpose_rates = region.get('land_purpose_rates', {})
                purpose_rates = land_purpose_rates.get(industrial_land_purpose)
                
                if purpose_rates:
                    return {
                        'up_to_10000': purpose_rates.get('up_to_10000_sqm', 0),
                        'above_10000': purpose_rates.get('above_10000_sqm', 0)
                    }
        
        # Если регион или назначение не найдено
        frappe.throw(f"Не найдены данные для территории '{territorial_unit_name}' и назначения '{industrial_land_purpose}'")
        
    except FileNotFoundError:
        frappe.throw("Файл с данными промышленных земель не найден. Обратитесь к администратору системы")
    except json.JSONDecodeError:
        frappe.throw("Ошибка чтения файла с данными промышленных земель")
    except Exception as e:
        frappe.throw(f"Ошибка при получении баллов промышленной земли: {str(e)}")

def calculate_industrial_land_formula(area_sqm, score_data):
    """
    Рассчитывает стоимость по прогрессивной формуле для промышленных земель
    """
    up_to_10000_score = score_data['up_to_10000']
    above_10000_score = score_data['above_10000']
    
    calculation_parts = []
    total = 0
    
    if area_sqm <= 10000:
        # Вся площадь до 10000 м²
        part_result = (area_sqm / 100) * up_to_10000_score
        total = part_result
        
        calculation_parts.append({
            'area': area_sqm,
            'score': up_to_10000_score,
            'formula': f"{area_sqm} ÷ 100 × {up_to_10000_score} = {part_result}",
            'result': part_result
        })
        
        formula_text = f"{area_sqm} ÷ 100 × {up_to_10000_score} = {total}"
        
    else:
        # Прогрессивная система: до 10000 м² + свыше 10000 м²
        
        # Первые 10000 м²
        part1_result = (10000 / 100) * up_to_10000_score
        calculation_parts.append({
            'area': 10000,
            'score': up_to_10000_score,
            'formula': f"10000 ÷ 100 × {up_to_10000_score} = {part1_result}",
            'result': part1_result
        })
        
        # Оставшаяся площадь свыше 10000 м²
        remaining_area = area_sqm - 10000
        part2_result = (remaining_area / 100) * above_10000_score
        calculation_parts.append({
            'area': remaining_area,
            'score': above_10000_score,
            'formula': f"{remaining_area} ÷ 100 × {above_10000_score} = {part2_result}",
            'result': part2_result
        })
        
        total = part1_result + part2_result
        formula_text = f"(10000 ÷ 100 × {up_to_10000_score}) + ({remaining_area} ÷ 100 × {above_10000_score}) = {part1_result} + {part2_result} = {total}"
    
    return {
        'total': total,
        'area_sqm': area_sqm,
        'formula': formula_text,
        'calculation_parts': calculation_parts,
        'scores_used': score_data
    }