package dao

import (
	"encoding/gob"
	"errors"
	"os"
	"sync"
)

type ProposalStore struct {
	mu        sync.RWMutex
	proposals map[uint64]*Proposal
	nextID    uint64
}

func NewProposalStore() *ProposalStore {
	return &ProposalStore{
		proposals: make(map[uint64]*Proposal),
		nextID:    1,
	}
}

func (ps *ProposalStore) Create(title, content, creator string, typ ProposalType, duration int64) *Proposal {
	ps.mu.Lock()
	defer ps.mu.Unlock()
	id := ps.nextID
	ps.nextID++
	p := NewProposal(id, title, content, creator, typ, duration)
	ps.proposals[id] = p
	return p
}

func (ps *ProposalStore) Get(id uint64) (*Proposal, error) {
	ps.mu.RLock()
	defer ps.mu.RUnlock()
	p, ok := ps.proposals[id]
	if !ok {
		return nil, errors.New("proposta não encontrada")
	}
	return p, nil
}

func (ps *ProposalStore) List() []*Proposal {
	ps.mu.RLock()
	defer ps.mu.RUnlock()
	var list []*Proposal
	for _, p := range ps.proposals {
		list = append(list, p)
	}
	return list
}

func (ps *ProposalStore) SaveToDisk(path string) error {
	ps.mu.RLock()
	defer ps.mu.RUnlock()
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()
	enc := gob.NewEncoder(f)
	return enc.Encode(ps)
}

func (ps *ProposalStore) LoadFromDisk(path string) error {
	ps.mu.Lock()
	defer ps.mu.Unlock()
	f, err := os.Open(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	defer f.Close()
	dec := gob.NewDecoder(f)
	return dec.Decode(ps)
}