using Microsoft.Playwright;

namespace Books.E2E.Tests.Pages;

/// <summary>
/// Page object for the Company Setup Wizard at /opret-virksomhed.
/// </summary>
public class CompanySetupWizardPage : BasePage
{
    // Selectors
    private readonly ILocator _companyNameInput;
    private readonly ILocator _cvrInput;
    private readonly ILocator _nextButton;
    private readonly ILocator _backButton;
    private readonly ILocator _submitButton;
    private readonly ILocator _successResult;
    private readonly ILocator _goToDashboardButton;

    public CompanySetupWizardPage(IPage page) : base(page)
    {
        _companyNameInput = page.GetByLabel("Virksomhedsnavn");
        _cvrInput = page.GetByLabel("CVR-nummer");
        _nextButton = page.Locator("button:has-text('Næste')");
        _backButton = page.Locator("button:has-text('Tilbage')");
        _submitButton = page.GetByRole(AriaRole.Button, new() { Name = "Opret virksomhed" });
        _successResult = page.Locator(".ant-result-success");
        _goToDashboardButton = page.GetByRole(AriaRole.Button, new() { Name = "Gå til dashboard" });
    }

    /// <summary>
    /// Waits for the wizard to be fully loaded.
    /// </summary>
    public async Task WaitForWizardToLoad()
    {
        // Wait for the welcome text
        await Page.GetByText("Velkommen til Books").WaitForAsync(new() { Timeout = 10000 });
        await WaitForNetworkIdleAsync();
    }

    /// <summary>
    /// Enters the company name.
    /// </summary>
    public async Task EnterCompanyName(string name)
    {
        await _companyNameInput.ClearAsync();
        await _companyNameInput.FillAsync(name);
    }

    /// <summary>
    /// Enters the CVR number.
    /// </summary>
    public async Task EnterCvr(string cvr)
    {
        await _cvrInput.ClearAsync();
        await _cvrInput.FillAsync(cvr);
    }

    /// <summary>
    /// Selects the country.
    /// </summary>
    public async Task SelectCountry(string country)
    {
        var countryLabel = country switch
        {
            "DK" => "Danmark",
            _ => country
        };
        await SelectAntOptionAsync("Land", countryLabel);
    }

    /// <summary>
    /// Selects the currency.
    /// </summary>
    public async Task SelectCurrency(string currency)
    {
        var currencyLabel = currency switch
        {
            "DKK" => "DKK - Danske kroner",
            "EUR" => "EUR - Euro",
            _ => currency
        };
        await SelectAntOptionAsync("Valuta", currencyLabel);
    }

    /// <summary>
    /// Selects the fiscal year start month.
    /// </summary>
    public async Task SelectFiscalYearStartMonth(int month)
    {
        var monthName = GetDanishMonthName(month);
        await SelectAntOptionAsync("Regnskabsår starter", monthName);
    }

    /// <summary>
    /// Sets whether the company is VAT registered.
    /// </summary>
    public async Task SelectVatRegistered(bool isRegistered)
    {
        var label = isRegistered
            ? "Ja, virksomheden er momsregistreret"
            : "Nej, ikke momsregistreret";
        await SelectAntOptionAsync("Momsregistreret", label);
    }

    /// <summary>
    /// Selects the VAT period frequency.
    /// </summary>
    public async Task SelectVatPeriod(string period)
    {
        var label = period switch
        {
            "MONTHLY" => "Månedlig",
            "QUARTERLY" => "Kvartalsvis",
            "HALFYEARLY" => "Halvårlig",
            _ => period
        };
        await SelectAntOptionAsync("Momsperiode", label);
    }

    /// <summary>
    /// Clicks the Next button to advance the wizard.
    /// </summary>
    public async Task ClickNext()
    {
        await _nextButton.ClickAsync();
        await WaitForNetworkIdleAsync();
        // Small delay for step transition animation
        await Task.Delay(300);
    }

    /// <summary>
    /// Clicks the Back button.
    /// </summary>
    public async Task ClickBack()
    {
        await _backButton.ClickAsync();
        await Task.Delay(300);
    }

    /// <summary>
    /// Submits the company creation form.
    /// </summary>
    public async Task SubmitForm()
    {
        await _submitButton.ClickAsync();

        // Wait for either success or error
        await Page.WaitForSelectorAsync(
            ".ant-result-success, .ant-message-error",
            new() { Timeout = 15000 });
    }

    /// <summary>
    /// Waits for the success result to appear.
    /// </summary>
    public async Task WaitForSuccessResult()
    {
        await _successResult.WaitForAsync(new() { Timeout = 10000 });
    }

    /// <summary>
    /// Clicks "Go to Dashboard" button.
    /// </summary>
    public async Task ClickGoToDashboard()
    {
        await _goToDashboardButton.ClickAsync();
        await WaitForNetworkIdleAsync();
    }

    /// <summary>
    /// Checks if validation error is visible.
    /// </summary>
    public async Task<bool> HasValidationError()
    {
        return await Page.Locator(".ant-form-item-explain-error").IsVisibleAsync();
    }

    /// <summary>
    /// Gets all visible validation error messages.
    /// </summary>
    public async Task<IReadOnlyList<string>> GetValidationErrors()
    {
        var errors = Page.Locator(".ant-form-item-explain-error");
        return await errors.AllTextContentsAsync();
    }

    private static string GetDanishMonthName(int month) => month switch
    {
        1 => "Januar",
        2 => "Februar",
        3 => "Marts",
        4 => "April",
        5 => "Maj",
        6 => "Juni",
        7 => "Juli",
        8 => "August",
        9 => "September",
        10 => "Oktober",
        11 => "November",
        12 => "December",
        _ => throw new ArgumentOutOfRangeException(nameof(month), month, "Month must be 1-12")
    };
}
