import { createContext, useContext, useMemo, useState } from 'react'
import { SEED_POLL } from '../data/seed'
import { readJson, writeJson, storageKeys } from '../lib/storage'

const PollContext = createContext(null)

function ensureSeed() {
  const existing = readJson(storageKeys.POLLS_KEY, null)
  if (existing?.length) return existing
  const seeded = [SEED_POLL]
  writeJson(storageKeys.POLLS_KEY, seeded)
  return seeded
}

export function PollProvider({ children }) {
  const [polls, setPolls] = useState(ensureSeed)
  const [votes, setVotes] = useState(() => readJson(storageKeys.VOTES_KEY, {}))

  const persistPolls = (next) => {
    setPolls(next)
    writeJson(storageKeys.POLLS_KEY, next)
  }

  const persistVotes = (next) => {
    setVotes(next)
    writeJson(storageKeys.VOTES_KEY, next)
  }

  const getPoll = (id) => polls.find((p) => p.id === id)

  const castVote = (pollId, optionId, userId) => {
    const voteKey = `${pollId}:${userId}`
    if (votes[voteKey]) {
      return { ok: false, error: 'You already cast a vote for this poll.' }
    }

    const nextPolls = polls.map((poll) => {
      if (poll.id !== pollId) return poll
      return {
        ...poll,
        options: poll.options.map((opt) =>
          opt.id === optionId ? { ...opt, votes: opt.votes + 1 } : opt,
        ),
      }
    })

    const nextVotes = {
      ...votes,
      [voteKey]: { pollId, optionId, userId, at: new Date().toISOString() },
    }

    persistPolls(nextPolls)
    persistVotes(nextVotes)
    return { ok: true }
  }

  const hasVoted = (pollId, userId) => Boolean(userId && votes[`${pollId}:${userId}`])

  const createPoll = ({ title, description, options }) => {
    const poll = {
      id: crypto.randomUUID(),
      title,
      description,
      status: 'open',
      createdAt: new Date().toISOString(),
      options: options.map((name, index) => ({
        id: String(index + 1),
        name,
        title: 'Nominee',
        votes: 0,
        gradient: ['from-rose-100 to-orange-100', 'from-blue-100 to-cyan-100', 'from-emerald-100 to-lime-100'][
          index % 3
        ],
      })),
    }
    persistPolls([poll, ...polls])
    return poll
  }

  const closePoll = (id) => {
    persistPolls(polls.map((p) => (p.id === id ? { ...p, status: 'closed' } : p)))
  }

  const deletePoll = (id) => {
    persistPolls(polls.filter((p) => p.id !== id))
  }

  const value = useMemo(
    () => ({
      polls,
      getPoll,
      castVote,
      hasVoted,
      createPoll,
      closePoll,
      deletePoll,
    }),
    [polls, votes],
  )

  return <PollContext.Provider value={value}>{children}</PollContext.Provider>
}

export function usePolls() {
  const ctx = useContext(PollContext)
  if (!ctx) throw new Error('usePolls must be used within PollProvider')
  return ctx
}
