"""Fixtures for the sage_validation tests."""
from unittest.mock import MagicMock

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from faker import Faker

from sage_validation.file_validator.models import MeoCostCentres, MeoValidSuppliers, XxData


@pytest.fixture
def sample_input_file() -> SimpleUploadedFile:
    """Create a sample valid CSV file for testing."""
    csv_headers_list = [
        "AccountNumber",
        "CBAccountNumber",
        "DaysDiscountValid",
        "DiscountValue",
        "DiscountPercentage",
        "DueDate",
        "GoodsValueInAccountCurrency",
        "PurControlValueInBaseCurrency",
        "DocumentToBaseCurrencyRate",
        "DocumentToAccountCurrencyRate",
        "PostedDate",
        "QueryCode",
        "TransactionReference",
        "SecondReference",
        "Source",
        "SYSTraderTranType",
        "TransactionDate",
        "UniqueReferenceNumber",
        "UserNumber",
        "TaxValue",
        "SYSTraderGenerationReasonType",
        "GoodsValueInBaseCurrency",

        # NominalAnalysis repeating columns (Example: /1 for first occurrence)
        "NominalAnalysisTransactionValue/1",
        "NominalAnalysisNominalAccountNumber/1",
        "NominalAnalysisNominalCostCentre/1",
        "NominalAnalysisNominalDepartment/1",
        "NominalAnalysisNominalAnalysisNarrative/1",
        "NominalAnalysisTransactionAnalysisCode/1",

        # TaxAnalysis repeating columns (Example: /1 for first occurrence)
        "TaxAnalysisTaxRate/1",
        "TaxAnalysisGoodsValueBeforeDiscount/1",
        "TaxAnalysisDiscountValue/1",
        "TaxAnalysisDiscountPercentage/1",
        "TaxAnalysisTaxOnGoodsValue/1",
    ]
    csv_headers = ",".join(csv_headers_list)

    csv_content_list = [
        "12345",  # AccountNumber
        "54321",  # CBAccountNumber
        "30",  # DaysDiscountValid
        "10.5",  # DiscountValue
        "5.0",  # DiscountPercentage
        "2024-02-10",  # DueDate
        "1000",  # GoodsValueInAccountCurrency
        "950",  # PurControlValueInBaseCurrency
        "1.2",  # DocumentToBaseCurrencyRate
        "1.1",  # DocumentToAccountCurrencyRate
        "2024-02-05",  # PostedDate
        "Q1",  # QueryCode
        "TRX123",  # TransactionReference
        "SREF123",  # SecondReference
        "80",  # Source
        "4",  # SYSTraderTranType
        "2024-02-01",  # TransactionDate
        "UR123",  # UniqueReferenceNumber
        "42",  # UserNumber
        "10",  # TaxValue
        "1000",  # SYSTraderGenerationReasonType
        "1200",  # GoodsValueInBaseCurrency

        # NominalAnalysis repeating values (Example: /1)
        "500.75",  # NominalAnalysisTransactionValue/1
        "ACC100",  # NominalAnalysisNominalAccountNumber/1
        "CC100",  # NominalAnalysisNominalCostCentre/1
        "DEP200",  # NominalAnalysisNominalDepartment/1
        "Sample Narrative",  # NominalAnalysisNominalAnalysisNarrative/1
        "TAC100",  # NominalAnalysisTransactionAnalysisCode/1

        # TaxAnalysis repeating values (Example: /1)
        "20.5",  # TaxAnalysisTaxRate/1
        "900",  # TaxAnalysisGoodsValueBeforeDiscount/1
        "30",  # TaxAnalysisDiscountValue/1
        "3.5",  # TaxAnalysisDiscountPercentage/1
        "180",  # TaxAnalysisTaxOnGoodsValue/1
    ]
    csv_content = ",".join(csv_content_list)

    return SimpleUploadedFile("test.csv", f"{csv_headers}\n{csv_content}".encode(), content_type="text/csv")

@pytest.fixture
def mock_meo_database(mocker: MagicMock)-> None:
    """Mock the meo database since it's read-only."""
    fake = Faker()

    # Mock MeoValidSuppliers
    supplier_mock = MagicMock()
    supplier_mock.all.return_value = [
        MeoValidSuppliers(
            supplier_account_number=str(fake.random_int(min=10000, max=99999)), supplier_account_name=fake.company()
        ),
        MeoValidSuppliers(supplier_account_number="12345", supplier_account_name="Sample Narrative")
    ]
    mocker.patch("sage_validation.file_validator.models.MeoValidSuppliers.objects.using", return_value=supplier_mock)

    # Mock MeoCostCentres
    cost_centre_mock = MagicMock()
    cost_centre_mock.all.return_value = [
        MeoCostCentres(cc="CC100", cc_type="Project", cc_name="CostCentreName", id=1),
        MeoCostCentres(cc="CC200", cc_type="Overhead", cc_name="OverheadName", id=2),
        MeoCostCentres(cc="CC300", cc_type="Overhead", cc_name="DepartmentName", id=3)
    ]
    mocker.patch("sage_validation.file_validator.models.MeoCostCentres.objects.using", return_value=cost_centre_mock)

    # Mock XxData
    xx_data_mock = MagicMock()
    xx_data_mock.all.return_value = [
        XxData(xx_value="N100", project="ProjectCode", overhead="OverheadCode", description=fake.sentence()),
        XxData(xx_value="N200", project="ProjectCode", overhead="OverheadCode", description=fake.sentence())
    ]
    mocker.patch("sage_validation.file_validator.models.XxData.objects.using", return_value=xx_data_mock)

    # Mock MeoValidSageAccounts
    sage_account_mock = MagicMock()
    sage_account_mock.filter.return_value.exists.return_value = True
    mocker.patch(
        "sage_validation.file_validator.models.MeoValidSageAccounts.objects.using", return_value=sage_account_mock
    )

    # Mock MeoNominal
    nominal_mock = MagicMock()
    nominal_mock.filter.return_value.exists.return_value = True
    mocker.patch("sage_validation.file_validator.models.MeoNominal.objects.using", return_value=nominal_mock)