/**
 * Votes store: vote sessions, individual votes, and result computation.
 *
 * Maps to the backend /api/v1/votes endpoints.
 */

export interface Vote {
  id: string
  session_id: string
  voter_id: string
  vote_value: string
  nuanced_level: number | null
  comment: string | null
  signature: string
  signed_payload: string
  voter_wot_status: string
  voter_is_smith: boolean
  voter_is_techcomm: boolean
  is_active: boolean
  created_at: string
}

export interface VoteSession {
  id: string
  decision_id: string | null
  item_version_id: string | null
  voting_protocol_id: string
  wot_size: number
  smith_size: number
  techcomm_size: number
  starts_at: string
  ends_at: string
  status: string
  votes_for: number
  votes_against: number
  votes_total: number
  smith_votes_for: number
  techcomm_votes_for: number
  threshold_required: number
  result: string | null
  chain_recorded: boolean
  chain_tx_hash: string | null
  created_at: string
}

export interface VoteResult {
  session_id: string
  status: string
  votes_for: number
  votes_against: number
  votes_total: number
  wot_size: number
  smith_size: number
  techcomm_size: number
  smith_votes_for: number
  techcomm_votes_for: number
  threshold_required: number
  result: string
  smith_threshold: number | null
  smith_pass: boolean
  techcomm_threshold: number | null
  techcomm_pass: boolean
}

export interface ThresholdDetails {
  wot_threshold: number
  smith_threshold: number | null
  techcomm_threshold: number | null
  wot_pass: boolean
  smith_pass: boolean | null
  techcomm_pass: boolean | null
  inertia_factor: number
  required_ratio: number
}

export interface VoteCreate {
  session_id: string
  vote_value: string
  nuanced_level?: number | null
  comment?: string | null
  signature: string
  signed_payload: string
}

export interface VoteSessionCreate {
  decision_id?: string | null
  item_version_id?: string | null
  voting_protocol_id: string
  wot_size?: number
  smith_size?: number
  techcomm_size?: number
}

export interface SessionFilters {
  status?: string
  voting_protocol_id?: string
  decision_id?: string
}

interface VotesState {
  currentSession: VoteSession | null
  votes: Vote[]
  result: VoteResult | null
  thresholdDetails: ThresholdDetails | null
  sessions: VoteSession[]
  loading: boolean
  error: string | null
}

export const useVotesStore = defineStore('votes', {
  state: (): VotesState => ({
    currentSession: null,
    votes: [],
    result: null,
    thresholdDetails: null,
    sessions: [],
    loading: false,
    error: null,
  }),

  getters: {
    isSessionOpen: (state): boolean => {
      if (!state.currentSession) return false
      return state.currentSession.status === 'open' && new Date(state.currentSession.ends_at) > new Date()
    },
    participationRate: (state): number => {
      if (!state.currentSession || state.currentSession.wot_size === 0) return 0
      return (state.currentSession.votes_total / state.currentSession.wot_size) * 100
    },
    forPercentage: (state): number => {
      if (!state.currentSession || state.currentSession.votes_total === 0) return 0
      return (state.currentSession.votes_for / state.currentSession.votes_total) * 100
    },
  },

  actions: {
    /**
     * Fetch a vote session by ID with its votes and result.
     */
    async fetchSession(sessionId: string) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()

        const [session, votes, result] = await Promise.all([
          $api<VoteSession>(`/votes/sessions/${sessionId}`),
          $api<Vote[]>(`/votes/sessions/${sessionId}/votes`),
          $api<VoteResult>(`/votes/sessions/${sessionId}/result`),
        ])

        this.currentSession = session
        this.votes = votes
        this.result = result
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Session de vote introuvable'
      } finally {
        this.loading = false
      }
    },

    /**
     * Submit a vote to the current session.
     */
    async submitVote(payload: VoteCreate) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const vote = await $api<Vote>(`/votes/sessions/${payload.session_id}/vote`, {
          method: 'POST',
          body: payload,
        })

        // Update local state
        this.votes.push(vote)

        // Refresh session tallies and result
        if (this.currentSession) {
          const [session, result] = await Promise.all([
            $api<VoteSession>(`/votes/sessions/${payload.session_id}`),
            $api<VoteResult>(`/votes/sessions/${payload.session_id}/result`),
          ])
          this.currentSession = session
          this.result = result
        }

        return vote
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors du vote'
        throw err
      } finally {
        this.loading = false
      }
    },

    /**
     * Fetch threshold details for a session.
     */
    async fetchThresholdDetails(sessionId: string) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        this.thresholdDetails = await $api<ThresholdDetails>(
          `/votes/sessions/${sessionId}/threshold`,
        )
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des details du seuil'
      } finally {
        this.loading = false
      }
    },

    /**
     * Close a vote session.
     */
    async closeSession(sessionId: string) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const session = await $api<VoteSession>(`/votes/sessions/${sessionId}/close`, {
          method: 'POST',
        })
        this.currentSession = session

        // Refresh result after closing
        this.result = await $api<VoteResult>(`/votes/sessions/${sessionId}/result`)
      } catch (err: any) {
        this.error = err?.data?.detail || err?.message || 'Erreur lors de la fermeture de la session'
        throw err
      } finally {
        this.loading = false
      }
    },

    /**
     * Fetch a list of vote sessions with optional filters.
     */
    async fetchSessions(filters?: SessionFilters) {
      this.loading = true
      this.error = null

      try {
        const { $api } = useApi()
        const query: Record<string, string> = {}
        if (filters?.status) query.status = filters.status
        if (filters?.voting_protocol_id) query.voting_protocol_id = filters.voting_protocol_id
        if (filters?.decision_id) query.decision_id = filters.decision_id

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

    /**
     * Create a new vote session.
     */
    async createSession(data: VoteSessionCreate) {
      this.loading = true
      this.error = null

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

    /**
     * Clear the current session state.
     */
    clearSession() {
      this.currentSession = null
      this.votes = []
      this.result = null
      this.thresholdDetails = null
    },
  },
})
