#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Скрипт конвертации classification_codes.txt в Frappe fixtures формат.

Usage:
    cd /home/frappe/frappe-bench/apps/invoice_az
    python3 invoice_az/scripts/convert_classification_codes_to_fixtures.py

Output:
    invoice_az/fixtures/classification_code.json
"""

import json
import os
from datetime import datetime
from collections import Counter

# Paths
SOURCE_FILE = "/home/frappe/frappe-bench/apps/invoice_az/classification_codes.txt"
OUTPUT_DIR = "/home/frappe/frappe-bench/apps/invoice_az/invoice_az/fixtures"
OUTPUT_FILE = os.path.join(OUTPUT_DIR, "classification_code.json")

# Constants
MODIFIED_TIMESTAMP = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")


def validate_record(record, index):
	"""Валидация отдельной записи"""
	errors = []

	# Проверка обязательных полей
	if not record.get('code'):
		errors.append(f"Record {index}: Missing code")

	if not record.get('name', {}).get('az'):
		errors.append(f"Record {index}: Missing name.az")

	# Проверка длины name_az
	name_az = record.get('name', {}).get('az', '')
	if len(name_az) > 2000:
		errors.append(f"Record {index}: name_az too long ({len(name_az)} chars)")

	return errors


def load_codes_from_file(file_path):
	"""Загрузка классификационных кодов из файла"""
	print(f"   Загрузка данных из {file_path}...")

	try:
		with open(file_path, 'r', encoding='utf-8') as f:
			source_data = json.load(f)
	except FileNotFoundError:
		print(f"   ✗ Файл не найден: {file_path}")
		return []
	except Exception as e:
		print(f"   ✗ Ошибка загрузки файла: {e}")
		return []

	codes = source_data.get('liabilities', [])
	print(f"   ✓ Загружено {len(codes)} записей")

	return codes


def convert_to_fixtures():
	"""Основная функция конвертации"""

	print("="*70)
	print("Classification Code Fixtures Generator")
	print("="*70)

	# 1. Загрузка исходных данных
	print(f"\n[1/5] Загрузка данных из файла...")

	codes = load_codes_from_file(SOURCE_FILE)

	# Проверка что файл загружен
	if not codes:
		print(f"\n   ✗ ERROR: Не удалось загрузить данные из файла")
		return False

	print(f"\n   ✓ Всего загружено {len(codes)} записей")

	# 2. Валидация данных
	print("\n[2/5] Валидация данных...")

	all_errors = []
	code_values = []

	for idx, code in enumerate(codes):
		errors = validate_record(code, idx)
		all_errors.extend(errors)
		code_values.append(code.get('code'))

	# Проверка уникальности кодов
	code_counts = Counter(code_values)
	duplicates = {code: count for code, count in code_counts.items() if count > 1}

	if duplicates:
		print(f"   ⚠ Найдены дубликаты кодов (будут пропущены):")
		for code, count in list(duplicates.items())[:10]:
			print(f"     - {code}: {count} раз")
		if len(duplicates) > 10:
			print(f"     ... и еще {len(duplicates) - 10} дубликатов")

	if all_errors:
		print(f"   ✗ Найдено {len(all_errors)} ошибок валидации:")
		for error in all_errors[:10]:  # Показываем первые 10
			print(f"     - {error}")
		if len(all_errors) > 10:
			print(f"     ... и еще {len(all_errors) - 10} ошибок")
		return False

	print(f"   ✓ Валидация пройдена успешно")

	# 3. Анализ данных
	print("\n[3/5] Анализ данных...")

	max_name_len = max(len(c['name']['az']) for c in codes)

	print(f"   - Максимальная длина name_az: {max_name_len} символов")
	print(f"   - Уникальных кодов: {len(set(code_values))}")

	# 4. Конвертация в fixtures формат
	print("\n[4/5] Конвертация в Frappe fixtures формат...")

	fixtures = []
	seen_codes = set()
	skipped_duplicates = 0

	for code_data in codes:
		code = code_data['code']

		# Пропускаем дубликаты (оставляем первое вхождение)
		if code in seen_codes:
			skipped_duplicates += 1
			continue

		seen_codes.add(code)

		fixture_record = {
			"docstatus": 0,
			"doctype": "Classification code",
			"modified": MODIFIED_TIMESTAMP,
			"name": code,  # autoname = field:code
			"code": code,
			"name_az": code_data['name']['az']
		}
		fixtures.append(fixture_record)

	print(f"   ✓ Конвертировано {len(fixtures)} записей")
	if skipped_duplicates > 0:
		print(f"   ⚠ Пропущено {skipped_duplicates} дубликатов")

	# 5. Сохранение в файл
	print(f"\n[5/5] Сохранение в {OUTPUT_FILE}...")

	# Создаем директорию fixtures если не существует
	os.makedirs(OUTPUT_DIR, exist_ok=True)

	try:
		with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
			json.dump(fixtures, f, ensure_ascii=False, indent=1)

		file_size = os.path.getsize(OUTPUT_FILE)
		print(f"   ✓ Файл сохранен успешно")
		print(f"   - Размер файла: {file_size / 1024:.2f} KB")

	except Exception as e:
		print(f"   ✗ Ошибка сохранения: {e}")
		return False

	# Итоговая статистика
	print("\n" + "="*70)
	print("РЕЗУЛЬТАТ:")
	print("="*70)
	print(f"✓ Успешно обработано {len(fixtures)} классификационных кодов")
	print(f"✓ Fixture файл: {OUTPUT_FILE}")
	print(f"✓ Готово к установке через bench migrate")
	print("="*70)

	return True


if __name__ == "__main__":
	success = convert_to_fixtures()
	exit(0 if success else 1)
