# frozen_string_literal: true

class GrantStockOptions
  def initialize(user, company:, option_pool:, board_approval_date:, vesting_commencement_date:,
                number_of_shares:, issue_date_relationship:, option_grant_type:, option_expiry_months:,
                vesting_trigger:, vesting_schedule_params:, voluntary_termination_exercise_months:,
                involuntary_termination_exercise_months:, termination_with_cause_exercise_months:,
                death_exercise_months:, disability_exercise_months:, retirement_exercise_months:, contract:)
    @user = user
    @option_pool = option_pool
    @company = company
    @board_approval_date = board_approval_date
    @vesting_commencement_date = vesting_commencement_date
    @number_of_shares = number_of_shares&.to_i
    @issue_date_relationship = issue_date_relationship
    @option_grant_type = option_grant_type
    @option_expiry_months = option_expiry_months&.to_i
    @vesting_trigger = vesting_trigger
    @vesting_schedule_params = vesting_schedule_params || {}
    @voluntary_termination_exercise_months = voluntary_termination_exercise_months
    @involuntary_termination_exercise_months = involuntary_termination_exercise_months
    @termination_with_cause_exercise_months = termination_with_cause_exercise_months
    @death_exercise_months = death_exercise_months
    @disability_exercise_months = disability_exercise_months
    @retirement_exercise_months = retirement_exercise_months
    @contract = contract
  end

  def process
    company_worker = user.company_worker_for(company)
    return { success: false, error: "Cannot use invoice vesting for #{user.display_name} as they are not an active contractor" } if vesting_trigger == EquityGrant.vesting_triggers[:invoice_paid] && !company_worker&.active?
    return { success: false, error: "Please set the company's conversion share price first" } if company.conversion_share_price_usd.nil?
    return { success: false, error: "Please set the company's current FMV (409A valuation) first" } if company.fmv_per_share_in_usd.nil?
    return { success: false, error: "Equity contract missing" } unless contract.present?

    company_investor =
      user.company_investors.find_or_create_by!(company:) do |investor|
        investor.investment_amount_in_cents = 0
        investor.user_id = user.id
      end

    if vesting_trigger == EquityGrant.vesting_triggers[:scheduled]
      vesting_schedule_id = vesting_schedule_params[:vesting_schedule_id]
      vesting_schedule = VestingSchedule.find_by(external_id: vesting_schedule_id) if vesting_schedule_id.present?
      vesting_schedule ||= VestingSchedule.find_or_create_by!(vesting_schedule_params.except(:vesting_schedule_id).to_h.symbolize_keys)
    end

    if vesting_trigger == EquityGrant.vesting_triggers[:scheduled] && vesting_schedule.present?
      period_started_at = Date.parse(vesting_commencement_date).beginning_of_day
      period_ended_at = period_started_at.end_of_day + vesting_schedule.total_vesting_duration_months.months
    else
      period_started_at = [company_worker.started_at, DateTime.current.beginning_of_year].max
      period_ended_at = period_started_at.end_of_year
    end
    exercise_price_usd = company.fmv_per_share_in_usd
    share_price_usd = company.conversion_share_price_usd

    ActiveRecord::Base.transaction do
      equity_grant_creation_result = EquityGrantCreation.new(company_investor:, option_pool:, option_grant_type:, share_price_usd:,
                                                             exercise_price_usd:, number_of_shares: @number_of_shares,
                                                             vested_shares: 0, period_started_at:, period_ended_at:,
                                                             issue_date_relationship:, option_expiry_months:,
                                                             board_approval_date:, vesting_trigger:, vesting_schedule:,
                                                             voluntary_termination_exercise_months:,
                                                             involuntary_termination_exercise_months:,
                                                             termination_with_cause_exercise_months:,
                                                             death_exercise_months:, disability_exercise_months:,
                                                             retirement_exercise_months:)
                                                        .process
      if equity_grant_creation_result.success?
        equity_grant = equity_grant_creation_result.equity_grant
        document = user.documents.build(equity_grant:,
                                        company:,
                                        year: Date.current.year,
                                        document_type: :equity_plan_contract)
        if contract.is_a?(String)
          document.text = contract
        else
          document.attachments.attach(contract)
        end
        document.signatures.build(user:, title: "Signer", signed_at: contract.is_a?(String) ? nil : Time.current)
        document.save!
        CompanyWorkerMailer.equity_grant_issued(equity_grant.id).deliver_later
        { success: true }
      else
        { success: false, error: equity_grant_creation_result.error }
      end
    end
  end

  private
    attr_reader :user, :option_pool, :option_grant_type, :company, :board_approval_date, :vesting_commencement_date,
                :issue_date_relationship, :option_expiry_months, :vesting_trigger, :vesting_schedule_params,
                :voluntary_termination_exercise_months, :involuntary_termination_exercise_months,
                :termination_with_cause_exercise_months, :death_exercise_months, :disability_exercise_months,
                :retirement_exercise_months, :contract
end
