/**
 * Protocols store: voting protocols and formula configurations.
 *
 * Maps to the backend /api/v1/protocols endpoints.
 */

export interface FormulaConfig {
  id: string
  name: string
  description: string | null
  duration_days: number
  majority_pct: number
  base_exponent: number
  gradient_exponent: number
  constant_base: number
  smith_exponent: number | null
  techcomm_exponent: number | null
  nuanced_min_participants: number | null
  nuanced_threshold_pct: number | null
  created_at: string
}

export interface VotingProtocol {
  id: string
  name: string
  description: string | null
  vote_type: string
  formula_config_id: string
  mode_params: string | null
  is_meta_governed: boolean
  created_at: string
  formula_config: FormulaConfig
}

export interface ProtocolCreate {
  name: string
  description: string | null
  vote_type: string
  formula_config_id: string
}

export interface FormulaCreate {
  name: string
  description?: string | null
  duration_days: number
  majority_pct: number
  base_exponent: number
  gradient_exponent: number
  constant_base: number
  smith_exponent?: number | null
  techcomm_exponent?: number | null
  nuanced_min_participants?: number | null
  nuanced_threshold_pct?: number | null
}

export interface SimulateParams {
  wot_size: number
  total_votes: number
  majority_pct: number
  base_exponent: number
  gradient_exponent: number
  constant_base: number
  smith_wot_size?: number
  smith_exponent?: number
  techcomm_size?: number
  techcomm_exponent?: number
}

export interface SimulateResult {
  threshold: number
  smith_threshold: number | null
  techcomm_threshold: number | null
  inertia_factor: number
  required_ratio: number
}

interface ProtocolsState {
  protocols: VotingProtocol[]
  formulas: FormulaConfig[]
  currentProtocol: VotingProtocol | null
  loading: boolean
  error: string | null
}

export const useProtocolsStore = defineStore('protocols', {
  state: (): ProtocolsState => ({
    protocols: [],
    formulas: [],
    currentProtocol: null,
    loading: false,
    error: null,
  }),

  getters: {
    binaryProtocols: (state): VotingProtocol[] => {
      return state.protocols.filter(p => p.vote_type === 'binary')
    },
    nuancedProtocols: (state): VotingProtocol[] => {
      return state.protocols.filter(p => p.vote_type === 'nuanced')
    },
    metaGovernedProtocols: (state): VotingProtocol[] => {
      return state.protocols.filter(p => p.is_meta_governed)
    },
  },

  actions: {
    /**
     * Fetch all voting protocols with their formula configurations.
     */
    async fetchProtocols(params?: { vote_type?: string }) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const query: Record<string, string> = {}
        if (params?.vote_type) query.vote_type = params.vote_type

        this.protocols = await $api<VotingProtocol[]>('/protocols/', { query })
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des protocoles'
      } finally {
        this.loading = false
      }
    },

    /**
     * Fetch all formula configurations.
     */
    async fetchFormulas() {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        this.formulas = await $api<FormulaConfig[]>('/protocols/formulas')
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des formules'
      } finally {
        this.loading = false
      }
    },

    /**
     * Fetch a single protocol by ID.
     */
    async fetchProtocolById(id: string) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        this.currentProtocol = await $api<VotingProtocol>(`/protocols/${id}`)
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Protocole introuvable'
      } finally {
        this.loading = false
      }
    },

    /**
     * Create a new voting protocol.
     */
    async createProtocol(data: ProtocolCreate) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const protocol = await $api<VotingProtocol>('/protocols/', {
          method: 'POST',
          body: data,
        })
        this.protocols.push(protocol)
        return protocol
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors de la creation du protocole'
        throw err
      } finally {
        this.loading = false
      }
    },

    /**
     * Create a new formula configuration.
     */
    async createFormula(data: FormulaCreate) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const formula = await $api<FormulaConfig>('/protocols/formulas', {
          method: 'POST',
          body: data,
        })
        this.formulas.push(formula)
        return formula
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors de la creation de la formule'
        throw err
      } finally {
        this.loading = false
      }
    },

    /**
     * Simulate formula computation on the backend.
     */
    async simulate(params: SimulateParams) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        return await $api<SimulateResult>('/protocols/simulate', {
          method: 'POST',
          body: params,
        })
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors de la simulation'
        throw err
      } finally {
        this.loading = false
      }
    },
  },
})
