import frappe
import json
import os
from frappe.model.document import Document

class Landtaxdeclaration(Document):
	pass

@frappe.whitelist()
def get_doctype_fields_info():
    result = {}
    
    try:
        elave1_meta = frappe.get_meta('Land tax declaration Elave 1')
        result['elave1_fields'] = []
        
        for field in elave1_meta.fields:
            field_info = {
                'fieldname': field.fieldname,
                'label': field.label,
                'fieldtype': field.fieldtype,
                'options': field.options or '',
                'reqd': field.reqd,
                'read_only': field.read_only
            }
            result['elave1_fields'].append(field_info)
        
        elave2_meta = frappe.get_meta('Land tax declaration Elave 2')
        result['elave2_fields'] = []
        
        for field in elave2_meta.fields:
            field_info = {
                'fieldname': field.fieldname,
                'label': field.label,
                'fieldtype': field.fieldtype,
                'options': field.options or '',
                'reqd': field.reqd,
                'read_only': field.read_only
            }
            result['elave2_fields'].append(field_info)
        
        asset_meta = frappe.get_meta('Asset')
        result['asset_fields'] = []
        
        for field in asset_meta.fields:
            field_info = {
                'fieldname': field.fieldname,
                'label': field.label,
                'fieldtype': field.fieldtype,
                'options': field.options or '',
                'reqd': field.reqd,
                'depends_on': field.depends_on or ''
            }
            result['asset_fields'].append(field_info)
        
        return result
        
    except Exception as e:
        return {'error': str(e)}

@frappe.whitelist()
def calculate_agricultural_tax(area_value, cadastral_district_name, quality_groups, agricultural_land_purpose, agricultural_purpose_name=None, tax_exempt_area=None):
    try:
        if area_value is None:
            frappe.throw("Area value is required")

        area_float = float(area_value)

        # Вычитаем освобожденную от налогов площадь
        if tax_exempt_area:
            try:
                exempt_float = float(tax_exempt_area)
                area_float = max(0, area_float - exempt_float)
            except (ValueError, TypeError):
                frappe.log_error(f"Invalid tax_exempt_area value: {tax_exempt_area}")

        # Если вся площадь освобождена, возвращаем 0
        if area_float <= 0:
            return {
                'tax_amount': 0,
                'calculation_details': {
                    'area_sqm': area_float,
                    'formula': 'All area is tax-exempt'
                }
            }

        # Для неиспользуемых земель: Area × 2%
        if agricultural_purpose_name == 'Təyinatı üzrə istifadə edilməyən kənd təsərrüfatı torpaqları üzrə hesablanmış vergi məbləği':
            result = area_float * 0.02

            return {
                'tax_amount': result,
                'calculation_details': {
                    'area_sqm': area_float,
                    'rate': 0.02,
                    'formula': f"{area_float} sq.m × 0.02 = {result}"
                }
            }

        # Для используемых земель: Hectare × Score × Markup
        if not cadastral_district_name or not quality_groups or not agricultural_land_purpose:
            frappe.throw("Not all fields are filled for calculation")

        hectare_value = area_float
        score = get_cadastral_score(cadastral_district_name, quality_groups)
        markup = get_markup_coefficient(agricultural_land_purpose)
        result = hectare_value * score * markup

        return {
            'tax_amount': result,
            'calculation_details': {
                'hectare': hectare_value,
                'score': score,
                'markup': markup,
                'formula': f"{hectare_value} ha × {score} × {markup} = {result}"
            }
        }

    except Exception as e:
        frappe.throw(f"Calculation error: {str(e)}")

def get_cadastral_score(cadastral_district_name, quality_group):
    try:
        json_file_path = frappe.get_app_path('taxes_az', 'data', 'cadastral_points_data.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)
                return score if score is not None else 0
        
        frappe.throw(f"Cadastral district '{cadastral_district_name}' not found in database")
        
    except FileNotFoundError:
        frappe.throw("Cadastral data file not found. Contact administrator")
    except json.JSONDecodeError:
        frappe.throw("Error reading cadastral data file")
    except Exception as e:
        frappe.throw(f"Error getting cadastral score: {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
    }
    
    coefficient = markup_map.get(agricultural_land_purpose)
    
    if coefficient is None:
        frappe.throw(f"Unknown land purpose type: {agricultural_land_purpose}")
    
    return coefficient

@frappe.whitelist()
def calculate_industrial_tax(area_sqm, territorial_unit_name, industrial_land_purpose, tax_exempt_area=None):
    try:
        if area_sqm is None or not territorial_unit_name or not industrial_land_purpose:
            frappe.throw("Not all fields are filled for calculation")

        area_sqm_float = float(area_sqm)

        # Вычитаем освобожденную от налогов площадь
        if tax_exempt_area:
            try:
                exempt_float = float(tax_exempt_area)
                area_sqm_float = max(0, area_sqm_float - exempt_float)
            except (ValueError, TypeError):
                frappe.log_error(f"Invalid tax_exempt_area value: {tax_exempt_area}")

        # Если вся площадь освобождена, возвращаем 0
        if area_sqm_float <= 0:
            return {
                'tax_amount': 0,
                'calculation_details': {
                    'area_sqm': area_sqm_float,
                    'formula': 'All area is tax-exempt'
                }
            }

        score_data = get_industrial_land_scores(territorial_unit_name, industrial_land_purpose)
        calculation_result = calculate_industrial_land_formula(area_sqm_float, score_data)

        return {
            'tax_amount': calculation_result['total'],
            'calculation_details': calculation_result
        }

    except Exception as e:
        frappe.throw(f"Calculation error: {str(e)}")

def get_industrial_land_scores(territorial_unit_name, industrial_land_purpose):
    try:
        json_file_path = frappe.get_app_path('taxes_az', 'data', 'industrial_land_data.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"Data not found for territory '{territorial_unit_name}' and purpose '{industrial_land_purpose}'")
        
    except FileNotFoundError:
        frappe.throw("Industrial land data file not found. Contact administrator")
    except json.JSONDecodeError:
        frappe.throw("Error reading industrial land data file")
    except Exception as e:
        frappe.throw(f"Error getting industrial land scores: {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:
        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:
        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
        })
        
        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
    }

@frappe.whitelist()
def get_assets_for_year(asset_type, year):
    try:
        target_year = int(year)
        
        filters = {
            'docstatus': 1,
            'custom_asset_type': asset_type
        }
        
        if asset_type == 'Kənd təsərrüfatı təyinatlı torpaq sahələri':
            fields = [
                'name',
                'asset_name',
                'agricultural_purpose',
                'cadastral_district_name',
                'cadastral_district_code',
                'quality_groups',
                'agricultural_land_purpose',
                'area',
                'tax_exempt_area',
                'purchase_date'
            ]
        else:
            fields = [
                'name', 
                'asset_name', 
                'territorial_unit_name',
                'territorial_unit_code',
                'industrial_land_purpose',
                'mining_note',
                'area',
                'tax_exempt_area',
                'purchase_date'
            ]
        
        assets = frappe.get_list('Asset', filters=filters, fields=fields)
        
        filtered_assets = []
        
        for asset in assets:
            if asset.get('purchase_date'):
                purchase_year = asset['purchase_date'].year
                
                if purchase_year == target_year:
                    filtered_assets.append(asset)
        
        return filtered_assets
        
    except Exception as e:
        return []