#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Normalize Tax Articles - fix Unicode normalization, curly quotes, and NBSP

This script:
1. Replaces non-breaking spaces (NBSP U+00A0) with regular spaces
2. Replaces typographic (curly) quotes with straight quotes
3. Normalizes Unicode to NFC form (composed characters)
4. Fixes both `name` and `article_name` fields

Run after migration to ensure all Tax Article names match the code mapping.
"""

import frappe
import unicodedata


def normalize_tax_articles():
	"""
	Normalize all Tax Article name and article_name values:
	- Replace non-breaking spaces (U+00A0) with regular spaces
	- Replace typographic quotes (U+201C, U+201D) with straight quotes (")
	- Normalize Unicode to NFC form
	"""

	if not frappe.db.table_exists("Tax Article"):
		frappe.log_error("Tax Article table does not exist, skipping normalization")
		return

	try:
		# Step 1: Replace non-breaking spaces (NBSP) with regular spaces
		# C2A0 = UTF-8 for U+00A0 (NBSP)
		# 20 = regular space

		frappe.db.sql("""
			UPDATE `tabTax Article`
			SET article_name = REPLACE(article_name, UNHEX('C2A0'), ' ')
			WHERE HEX(article_name) LIKE '%C2A0%'
		""")
		nbsp_article_fixed = frappe.db.sql("SELECT ROW_COUNT()")[0][0]

		frappe.db.sql("""
			UPDATE `tabTax Article`
			SET name = REPLACE(name, UNHEX('C2A0'), ' ')
			WHERE HEX(name) LIKE '%C2A0%'
		""")
		nbsp_name_fixed = frappe.db.sql("SELECT ROW_COUNT()")[0][0]

		# Also fix NBSP in Sales Invoice Item tax_article references
		if frappe.db.table_exists("Sales Invoice Item"):
			frappe.db.sql("""
				UPDATE `tabSales Invoice Item`
				SET tax_article = REPLACE(tax_article, UNHEX('C2A0'), ' ')
				WHERE HEX(tax_article) LIKE '%C2A0%'
			""")
			nbsp_ref_fixed = frappe.db.sql("SELECT ROW_COUNT()")[0][0]
		else:
			nbsp_ref_fixed = 0

		# Step 2: Replace curly quotes with straight quotes using HEX
		# E2809C = left curly quote \u201c
		# E2809D = right curly quote \u201d
		# 22 = straight quote "

		frappe.db.sql("""
			UPDATE `tabTax Article`
			SET article_name = REPLACE(
				REPLACE(article_name, UNHEX('E2809C'), '"'),
				UNHEX('E2809D'), '"'
			)
			WHERE HEX(article_name) LIKE '%E2809C%'
			   OR HEX(article_name) LIKE '%E2809D%'
		""")

		quotes_fixed = frappe.db.sql("SELECT ROW_COUNT()")[0][0]

		# Step 3: Normalize Unicode to NFC form
		articles = frappe.db.sql("""
			SELECT name, article_name
			FROM `tabTax Article`
			WHERE article_name IS NOT NULL AND article_name != ''
		""", as_dict=True)

		nfc_fixed = 0
		encoding_errors = 0

		for article in articles:
			try:
				original = article['article_name']

				# Handle potential encoding issues
				if isinstance(original, bytes):
					original = original.decode('utf-8', errors='replace')

				normalized = unicodedata.normalize('NFC', original)

				if original != normalized:
					frappe.db.sql("""
						UPDATE `tabTax Article`
						SET article_name = %s
						WHERE name = %s
					""", (normalized, article['name']))
					nfc_fixed += 1

			except (UnicodeDecodeError, UnicodeEncodeError, TypeError) as e:
				encoding_errors += 1
				frappe.log_error(
					f"Encoding error in Tax Article {article['name']}: {str(e)}",
					"Tax Article Encoding Error"
				)

		frappe.db.commit()

		total_fixed = nbsp_article_fixed + nbsp_name_fixed + nbsp_ref_fixed + quotes_fixed + nfc_fixed
		if total_fixed > 0:
			parts = []
			if nbsp_article_fixed > 0 or nbsp_name_fixed > 0:
				parts.append(f"{nbsp_article_fixed + nbsp_name_fixed} NBSP fixed")
			if nbsp_ref_fixed > 0:
				parts.append(f"{nbsp_ref_fixed} NBSP in references fixed")
			if quotes_fixed > 0:
				parts.append(f"{quotes_fixed} curly quotes fixed")
			if nfc_fixed > 0:
				parts.append(f"{nfc_fixed} NFC normalized")
			if encoding_errors > 0:
				parts.append(f"{encoding_errors} encoding errors")
			message = f"Tax Articles normalized: {', '.join(parts)}"
			print(message)
			frappe.log_error(message, "Tax Article Normalization")
		else:
			print("Tax Articles: Already normalized, no changes needed")

	except Exception as e:
		frappe.log_error(f"Error normalizing Tax Articles: {str(e)}", "Tax Article Normalization Error")
		raise


def normalize_on_migrate():
	"""
	Called by hooks.py after_migrate
	"""
	try:
		normalize_tax_articles()
	except Exception as e:
		# Don't fail migration if normalization fails
		frappe.log_error(f"Tax Article normalization failed: {str(e)}", "Migration Warning")
		print(f"Warning: Tax Article normalization failed: {str(e)}")
