namespace TaxBaik.Infrastructure.Repositories;

using Dapper;
using TaxBaik.Domain.Entities;
using TaxBaik.Domain.Interfaces;

public class TaxProfileRepository(IDbConnectionFactory connectionFactory) : BaseRepository(connectionFactory), ITaxProfileRepository
{
    public async Task<int> CreateAsync(TaxProfile profile, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryFirstAsync<int>(
            @"INSERT INTO tax_profiles (client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at)
              VALUES (@ClientId, @BusinessRegistration, @BusinessType, @EstablishmentDate, @AnnualRevenueRange,
              @EmployeeCount, @AccountingMethod, @FiscalYearEnd, @LastFilingDate, @NextFilingDueDate,
              @TaxRiskLevel, @PreviousAuditHistory, @SpecialNotes, NOW(), NOW())
              RETURNING id",
            profile);
    }

    public async Task<TaxProfile?> GetByIdAsync(int id, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryFirstOrDefaultAsync<TaxProfile>(
            @"SELECT id, client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at
              FROM tax_profiles WHERE id = @Id",
            new { Id = id });
    }

    public async Task<IEnumerable<TaxProfile>> GetAllAsync(CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryAsync<TaxProfile>(
            @"SELECT id, client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at
              FROM tax_profiles ORDER BY id DESC");
    }

    public async Task<TaxProfile?> GetByClientIdAsync(int clientId, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryFirstOrDefaultAsync<TaxProfile>(
            @"SELECT id, client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at
              FROM tax_profiles WHERE client_id = @ClientId",
            new { ClientId = clientId });
    }

    public async Task UpdateAsync(TaxProfile profile, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        await conn.ExecuteAsync(
            @"UPDATE tax_profiles SET business_registration = @BusinessRegistration, business_type = @BusinessType,
              establishment_date = @EstablishmentDate, annual_revenue_range = @AnnualRevenueRange,
              employee_count = @EmployeeCount, accounting_method = @AccountingMethod, fiscal_year_end = @FiscalYearEnd,
              last_filing_date = @LastFilingDate, next_filing_due_date = @NextFilingDueDate,
              tax_risk_level = @TaxRiskLevel, previous_audit_history = @PreviousAuditHistory,
              special_notes = @SpecialNotes, updated_at = NOW()
              WHERE id = @Id",
            profile);
    }

    public async Task<IEnumerable<TaxProfile>> GetByRiskLevelAsync(string riskLevel, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryAsync<TaxProfile>(
            @"SELECT id, client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at
              FROM tax_profiles WHERE tax_risk_level = @RiskLevel ORDER BY client_id",
            new { RiskLevel = riskLevel });
    }

    public async Task<IEnumerable<TaxProfile>> GetUpcomingFilingDuesAsync(DateTime startDate, DateTime endDate, CancellationToken cancellationToken = default)
    {
        using var conn = Conn();
        return await conn.QueryAsync<TaxProfile>(
            @"SELECT id, client_id, business_registration, business_type, establishment_date,
              annual_revenue_range, employee_count, accounting_method, fiscal_year_end, last_filing_date,
              next_filing_due_date, tax_risk_level, previous_audit_history, special_notes, created_at, updated_at
              FROM tax_profiles WHERE next_filing_due_date BETWEEN @StartDate AND @EndDate
              ORDER BY next_filing_due_date",
            new { StartDate = startDate, EndDate = endDate });
    }
}
