# frozen_string_literal: true

class UserPresenter
  delegate :country_code, :citizenship_country_code, :street_address, :city, :state, :zip_code, :email,
           :documents, :business_name, :business_entity?, :display_country,
           :legal_name, :preferred_name, :display_name, :billing_entity_name, :unconfirmed_email,
           :created_at, :state, :city, :zip_code, :street_address, :bank_account, :contracts, :tax_id, :birth_date,
           :requires_w9?, :tax_information_confirmed_at, :minimum_dividend_payment_in_cents, :bank_accounts,
           :tax_id_status, private: true, to: :user, allow_nil: true

  def initialize(current_context:)
    @current_context = current_context
    @user = current_context.user
    @company = current_context.company
    @company_administrator = current_context.company_administrator
    @company_worker = current_context.company_worker
    @company_investor = current_context.company_investor
    @company_lawyer = current_context.company_lawyer
  end

  def logged_in_user
    roles = {}
    has_documents = documents.joins(:signatures).not_consulting_contract.or(documents.unsigned).exists?
    if user.company_administrator_for?(company)
      administrator = user.company_administrator_for(company)
      roles[Company::ACCESS_ROLE_ADMINISTRATOR] = {
        id: administrator.id.to_s,
        isInvited: !!user.invited_by&.company_worker_for?(company),
      }
    end
    if user.company_lawyer_for?(company)
      roles[Company::ACCESS_ROLE_LAWYER] = {
        id: user.company_lawyer_for(company).external_id,
      }
    end
    if user.company_investor_for?(company)
      investor = user.company_investor_for(company)
      roles[Company::ACCESS_ROLE_INVESTOR] = {
        id: investor.external_id,
        deactivatedAt: investor.deactivated_at,
        hasDocuments: has_documents,
        hasGrants: investor.equity_grants.accepted.eventually_exercisable.exists?,
        hasShares: investor.share_holdings.exists?,
        hasConvertibles: investor.convertible_securities.exists?,
        investedInAngelListRuv: investor.invested_in_angel_list_ruv,
      }
    end
    if user.company_worker_for?(company)
      worker = user.company_worker_for(company)
      roles[Company::ACCESS_ROLE_WORKER] = {
        id: worker.external_id,
        hasDocuments: has_documents,
        endedAt: worker.ended_at,
        payRateType: worker.pay_rate_type,
        role: worker.role,
        payRateInSubunits: worker.pay_rate_in_subunits,
        equityPercentage: worker.equity_percentage,
      }
    end

    {
      companies: user.all_companies.compact.map do |company|
        flags = []
        flags.push("equity") if company.equity_enabled?
        flags.push("company_updates") if company.company_investors.active.exists?
        flags.push("option_exercising") if company.json_flag?("option_exercising")
        can_view_financial_data = user.company_administrator_for?(company) || user.active_company_investor_for?(company)
        {
          **company_navigation_props(
            company:,
          ),
          address: {
            street_address: company.street_address,
            city: company.city,
            zip_code: company.zip_code,
            state: company.state,
            country_code: company.country_code,
            country: ISO3166::Country[company.country_code].common_name,
          },
          flags:,
          equityEnabled: company.equity_enabled,
          requiredInvoiceApprovals: company.required_invoice_approval_count,
          paymentProcessingDays: company.contractor_payment_processing_time_in_days,
          createdAt: company.created_at.iso8601,
          fullyDilutedShares: can_view_financial_data ? company.fully_diluted_shares : nil,
          valuationInDollars: can_view_financial_data ? company.valuation_in_dollars : nil,
          sharePriceInUsd: can_view_financial_data ? company.share_price_in_usd.to_s : nil,
          conversionSharePriceUsd: can_view_financial_data ? company.conversion_share_price_usd.to_s : nil,
          exercisePriceInUsd: can_view_financial_data ? company.fmv_per_share_in_usd.to_s : nil,
          investorCount: user.company_administrator_for?(company) ? company.company_investors.active.where.not(user_id: company.company_workers.active.select(:user_id)).count : nil,
          contractorCount: user.company_administrator_for?(company) ? company.company_workers.active.count : nil,
          primaryAdminName: company.primary_admin.user.name,
          completedPaymentMethodSetup: company.bank_account_ready?,
          isTrusted: company.is_trusted,
          checklistItems: company.checklist_items(user),
          checklistCompletionPercentage: company.checklist_completion_percentage(user),
          externalId: company.external_id,
        }
      end,
      id: user.external_id,
      currentCompanyId: company&.external_id,
      name: user.display_name,
      legalName: legal_name,
      preferredName: preferred_name,
      billingEntityName: billing_entity_name,
      roles:,
      hasPayoutMethodForInvoices: user.bank_account.present?,
      hasPayoutMethodForDividends: user.bank_account_for_dividends.present?,
      address: {
        street_address: user.street_address,
        city: user.city,
        zip_code: user.zip_code,
        state: user.state,
        country_code: user.country_code,
        country: user.country_code && ISO3166::Country[user.country_code].common_name,
      },
      email: user.display_email,
      onboardingPath: worker && worker.role.nil? ? "/documents" : nil,
      taxInformationConfirmedAt: tax_information_confirmed_at&.iso8601,
    }
  end

  private
    attr_reader :current_context, :user, :company, :company_administrator, :company_worker, :company_investor, :company_lawyer

    def company_navigation_props(company:)
      CompanyNavigationPresenter.new(user: current_context.user, company:).props
    end
end
