from db.models.LancamentoDespesa import VariavelValidado
from ..models.Servico import TipoServico
from ..models.MovimentacaoEstoque import SituacaoMovimentacaoEstoque

from datetime import timedelta, datetime

from pydantic import BaseModel

from enum import Enum


class UsuarioBase(BaseModel):
    nome: str
    login: str


class UsuarioCreate(UsuarioBase):
    senha: str


class Usuario(UsuarioBase):
    id: int

    class Config:
        orm_mode: True


class ProdutoBase(BaseModel):
    nome: str
    valor: float


class ProdutoComIdDoUsuario(ProdutoBase):
    usuario_id: int | None = None


class Produto(ProdutoBase):
    id: int

    class Config:
        orm_mode: True


class ProdutoComUsuario(Produto):
    usuario: Usuario

class MovimentacaoEstoqueCadastro(BaseModel):
    quantidade: int
    orcamento_id: int | None = None
    produto_id: int
    situacao: SituacaoMovimentacaoEstoque | None = None
    data: str | None = None

class MovimentacaoEstoqueAtualizacao (BaseModel):
    id: int
    quantidade: int | None = None
    situacao: SituacaoMovimentacaoEstoque | None = None
    data: str | None = None

class MovimentacaoEstoque(BaseModel):
    id: int
    quantidade: int
    produto: Produto

class EstoqueProduto(BaseModel):
    produto: Produto
    total_no_estoque: int
    total_reservado: int

class ServicoBase(BaseModel):
    nome: str
    valor: float
    tipo: TipoServico


class Servico(ServicoBase):
    id: int

    class Config:
        orm_mode: True


class ServicoComIdDoUsuario(ServicoBase):
    usuario_id: int | None = None


class ServicoComUsuario(Servico):
    usuario: Usuario

    class Config:
        orm_mode: True


class UsuarioComProdutosEServicos(Usuario):
    produtos: list[Produto] = []
    servicos: list[Servico] = []

    class Config:
        orm_mode: True


class ClienteBase(BaseModel):
    cep: str
    logradouro: str
    bairro: str
    cidade: str
    estado: str
    numero: int
    complemento: str
    licenca_operacional: str
    email: str
    telefone: str


class ClienteComIdDoUsuario(ClienteBase):
    usuario_id: int | None = None


class Cliente(ClienteBase):
    id: int


class ClienteComUsuario(Cliente):
    usuario: Usuario


class PessoaFisicaBase(ClienteBase):
    nome_completo: str
    cpf: str


class PessoaFisicaComIdDoUsuario(PessoaFisicaBase):
    usuario_id: int | None = None

class PessoaJuridicaBase(ClienteBase):
    razao_social: str
    cnpj: str
    contato: str
    responsavel: str

class PessoaJuridicaComIdDoUsuario(ClienteBase):
    usuario_id: int | None = None

class ClienteRecebidoPeloBody(ClienteBase):
    razao_social: str | None = None
    cnpj: str | None = None
    contato: str | None = None
    responsavel: str | None = None
    nome_completo: str | None = None
    cpf: str | None = None
    tipo_cliente: str

class ClienteRecebidoPeloBodyComIdUsuario(ClienteRecebidoPeloBody):
    usuario_id: int | None = None

class FuncionarioBase(BaseModel):
    nome: str
    cpf: str
    rg: str
    email: str
    telefone: str
    cep: str
    logradouro: str
    bairro: str
    cidade: str
    estado: str
    numero: int
    complemento: str
    data_nascimento: str | int
    data_admissao: str | int
    nome_pai: str
    nome_mae: str
    funcao: str
    salario_base: float
    banco: str
    agencia: str
    conta: str
    titular: str
    pix: str

class FuncionarioComIdDoUsuario(FuncionarioBase):
    usuario_id: int | None = None

class Funcionario(FuncionarioComIdDoUsuario):
    id: int

class FornecedorBase(BaseModel):
    razao_social: str
    nome_fantasia: str
    responsavel: str
    cep: str
    logradouro: str
    bairro: str
    cidade: str
    estado: str
    numero: int
    complemento: str
    email: str
    telefone: str
    observacoes: str
    cnpj: str
    banco: str
    agencia: str
    conta: str
    titular: str
    pix: str

class FornecedorComIdDoUsuario(FornecedorBase):
    usuario_id: int | None = None

class VisitaComercialBase(BaseModel):
    nome_da_empresa: str
    data_da_visita: str
    cep: str
    logradouro: str
    bairro: str
    cidade: str
    estado: str
    numero: int
    complemento: str
    contato: str
    telefone: str
    descricao: str

class VisitaComercialComIdDoUsuario(VisitaComercialBase):
    usuario_id: int | None = None

class ReagendamentoBase(BaseModel):
    visita_comercial_id: int
    data_da_visita: str

class DespesaBase(BaseModel):
    id: int | None = None
    usuario_id: int | None = None
    nome: str
    data: str
    modo: str
    anexo: str | None = None
    anexo_caminho: str | None = None
    descricao: str
    tipo_tempo: str
    periodo: str
    tipo_despesa: str
    valor_primeiro_lancamento: float

class DespesaParaLancamento(BaseModel):
    id: int
    data: datetime
    valor: float
    tipo_tempo: str
    periodo: str | int

class ProdutosOrcamento(BaseModel):
    orcamento_id: int | None = None
    produto_id: int
    quantidade: int = 0
    preco_unitario: float = 0.00

class ServicosOrcamento(BaseModel):
    orcamento_id: int | None = None
    servico_id: int
    tempo: str = "00:00:00"
    preco_por_hora: float = 0.00

class OrcamentoBase(BaseModel):
    id: int | None = None
    usuario_id: int | None = None
    cliente_id: int | None = None
    tipo: str = "Mensal"
    situacao: str = "Pendente"
    data_emissao: str
    produtos: list[ProdutosOrcamento] = []
    servicos: list[ServicosOrcamento] = []

class LancamentoReceitaBase(BaseModel):
    id: int | None = None
    orcamento_id: int
    data: str
    valor: float

class LancamentoDespesaBase(BaseModel):
    id: int | None = None
    despesa_id: int
    data_lancamento: str
    valor: float
    variavel_validado: VariavelValidado

class ValidacaoDespesaVariavel(BaseModel):
    id: int | None = None
    valor: float

class LancamentoReceita(LancamentoReceitaBase):
    nome_orcamento: str

class LancamentoDespesa(LancamentoDespesaBase):
    nome_despesa: str

class LancamentoParaValidacao(BaseModel):
    id: int
    nome_despesa: str
    data_lancamento: str

class ItemGrafico(BaseModel):
    data: datetime
    total: float
    
class Estatisticas(BaseModel):
    total_de_receitas_este_mes: float
    total_de_despesas_este_mes: float
    proximas_receitas: list[LancamentoReceita]
    proximas_despesas: list[LancamentoDespesa]
    grafico: list[ItemGrafico]
    lancamentos_para_validacao: list[LancamentoParaValidacao]

class TipoPeriodoLancamento(Enum):
    DIARIO = "Diario"
    SEMANAL = "Semanal"
    MENSAL = "Mensal"
    BIMESTRAL = "Bimestral"
    TRIMESTRAL = "Trimestral"
    SEMESTRAL = "Semestral"
    ANUAL = "Anual"
    VARIAVEL = "Variavel"

class PeriodoLancamento(BaseModel):
    tipo: TipoPeriodoLancamento
    valor_variavel: int | None = None
