use crate::db::Database;
use crate::export_json::ExportData;
use crate::models::{NewCategory, NewTransaction};
use std::path::Path;

pub fn import_json(db: &Database, path: &Path, merge: bool) -> Result<usize, Box<dyn std::error::Error>> {
    let content = std::fs::read_to_string(path)?;
    let data: ExportData = serde_json::from_str(&content)?;

    if !merge {
        db.reset_all_data()?;
    }

    for cat in &data.categories {
        let existing = db.list_categories(Some(cat.transaction_type))?;
        if !existing.iter().any(|c| c.name == cat.name) {
            let new_cat = NewCategory {
                name: cat.name.clone(),
                icon: cat.icon.clone(),
                color: cat.color.clone(),
                transaction_type: cat.transaction_type,
                sort_order: cat.sort_order,
                parent_id: None,
            };
            db.insert_category(&new_cat)?;
        }
    }

    let mut count = 0;
    for txn in &data.transactions {
        let categories = db.list_categories(Some(txn.transaction_type))?;
        let original_cat = data.categories.iter().find(|c| c.id == txn.category_id);
        let category_id = match original_cat {
            Some(oc) => categories.iter().find(|c| c.name == oc.name).map(|c| c.id),
            None => None,
        };
        let Some(category_id) = category_id else { continue };

        if merge && db.find_duplicate_transaction(txn.amount, txn.transaction_type, category_id, txn.date)? {
            continue;
        }

        let new_txn = NewTransaction {
            amount: txn.amount,
            transaction_type: txn.transaction_type,
            category_id,
            currency: txn.currency.clone(),
            exchange_rate: txn.exchange_rate,
            note: txn.note.clone(),
            date: txn.date,
            recurring_id: None,
            payee: txn.payee.clone(),
        };
        db.insert_transaction(&new_txn)?;
        count += 1;
    }

    Ok(count)
}
