use crate::{
    commands::not_available,
    database::Result,
    entities::Bank,
    jobber::{JobberGet, JobberIter, JobberWork},
};

pub(crate) struct CompanyView {
    pub(crate) name: String,
    pub(crate) street: String,
    pub(crate) zip: String,
    pub(crate) city: String,
    pub(crate) email: Option<String>,
    pub(crate) phone: Option<String>,
    pub(crate) vat: Option<String>,
    pub(crate) bank: Option<Bank>,
    pub(crate) register: String,
}

impl CompanyView {
    pub(crate) fn new(
        database: &(impl JobberGet + JobberIter + JobberWork),
        ansi: bool,
    ) -> Result<Self> {
        let company = database.get_company()?;
        let address = &company.address;
        Ok(Self {
            name: address.name.clone(),
            street: address.street.clone(),
            zip: address.zip.clone(),
            city: address.city.clone(),
            email: company.email.clone(),
            phone: company.phone.clone(),
            vat: company.vat.clone(),
            bank: company.bank.clone(),
            register: company.register.clone().unwrap_or(not_available(ansi)),
        })
    }
}

impl std::fmt::Display for CompanyView {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, " Company Name: {}", self.name)?;
        writeln!(f, "       Street: {}", self.street)?;
        writeln!(f, "     ZIP code: {}", self.zip)?;
        writeln!(f, "         City: {}", self.city)?;
        if let Some(email) = &self.email {
            writeln!(f, "       E-Mail: {}", email)?;
        }
        if let Some(phone) = &self.phone {
            writeln!(f, " Phone number: {}", phone)?;
        }
        if let Some(vat) = &self.vat {
            writeln!(f, "          Vat: {}", vat)?;
        }
        if let Some(bank) = &self.bank {
            writeln!(f, "         Bank: {}", bank.name)?;
            writeln!(f, "         IBAN: {}", bank.iban)?;
            write!(f, "          BIC: {}", bank.bic)?;
        }
        Ok(())
    }
}
