using Back.Data.Models;
using Shared.DTOs;

namespace Back.Services
{
    public class PreparationHeaderTaxInvoice
    {
        private readonly Invoice _invoice;
        private readonly ActionTaxPayer _actionTaxPayer;
        private readonly int level;

        public PreparationHeaderTaxInvoice(Invoice invoice, ActionTaxPayer actionTaxPayer)
        {
            _invoice = invoice;
            _actionTaxPayer = actionTaxPayer;
            level = _invoice.pattern.ID;
        }

        #region Header
        public string Taxid { get { return _actionTaxPayer.GenerateTaxid(_invoice.inno, _invoice.InvoiceDate.Replace("/", "").Trim()); } }
        public long? Indatim { get { return _invoice.indatim ?? null; } }
        public long? Indati2m { get { return _invoice.Indati2m ?? null; } }
        public int? Inty { get { return _invoice.inty ?? 1; } }
        public string? Inno { get { return string.IsNullOrEmpty(_invoice.inno) ? null : _invoice.inno; } }
        public string? Irtaxid
        {
            get
            {
                return _invoice.invoiceType == InvoiceType.BackFrmSale || _invoice.invoiceType == InvoiceType.Repair ? _invoice.invoice.taxid
                    : _invoice.invoiceType == InvoiceType.Cancellation ? _invoice.taxid : null;
            }
        }
        public int? Inp { get { return _invoice.inp ?? 1; } }
        public int? Ins { get { return _invoice.ins ?? 1; } }
        public string? Tins { get { return string.IsNullOrEmpty(_invoice.tins) ? null : _invoice.tins; } }
        public int? Tob { get { return level == 10 || _invoice.tob == 0 ? null : _invoice.tob == 5 ? 1 : _invoice.tob == 6 ? 4 : _invoice.tob; } }
        public string? Bid
        {
            get
            {
                return level == 10 || string.IsNullOrEmpty(_invoice.bid) || !string.IsNullOrEmpty(_invoice.tinb)
                    || _invoice.tob == 1 || _invoice.tob == 2 || _invoice.tob == 3 || _invoice.tob == 4 ? null : _invoice.bid;
            }
        }
        public string? Tinb { get { return level == 10 || string.IsNullOrEmpty(_invoice.tinb) || _invoice.tob == 5 || _invoice.tob == 6 ? null : _invoice.tinb; } }
        public string? Sbc { get { return string.IsNullOrEmpty(_invoice.sbc) ? null : _invoice.sbc; } }
        public string? Bpc
        {
            get
            {
                return level == 10 || string.IsNullOrEmpty(_invoice.bpc) || !string.IsNullOrEmpty(_invoice.tinb)
                    || _invoice.tob == 1 || _invoice.tob == 2 || _invoice.tob == 3 || _invoice.tob == 4 ? null : _invoice.bpc;
            }
        }
        public string? Bbc { get { return level == 10 || string.IsNullOrEmpty(_invoice.bbc) ? null : _invoice.bbc; } }
        public int? Ft { get { return level == 9 ? _invoice.ft : null; } }
        public string? Bpn { get { return (level == 9 || level == 4) && !string.IsNullOrEmpty(_invoice.bpn) ? _invoice.bpn : null; } }
        public string? Scln { get { return (level == 3 || level == 4) && !string.IsNullOrEmpty(_invoice.scln) ? _invoice.scln : null; } }
        public string? Scc { get { return (level == 3 || level == 4 || level == 10) && !string.IsNullOrEmpty(_invoice.scc) ? _invoice.scc : null; } }
        public string? Cdcn { get { return level == 10 ? _invoice.cdcn : null; } }
        public int? Cdcd { get { return level == 10 ? _invoice.cdcd : null; } }
        public string? Crn { get { return (level == 3 || level == 4 || level == 5 || level == 6) && !string.IsNullOrEmpty(_invoice.crn) ? _invoice.crn : null; } }
        public string? Billid { get { return level == 8 ? _invoice.billid : null; } }
        public decimal? Tprdis { get { return level == 10 ? null : _invoice.tprdis ?? null; } }
        public decimal? Tdis { get { return level == 10 ? null : _invoice.tdis ?? null; } }
        public decimal? Tadis { get { return level == 10 ? null : _invoice.tadis ?? null; } }
        public decimal? Tvam { get { return _invoice.tvam ?? null; } }
        public decimal? Todam { get { return _invoice.todam ?? null; } }
        public decimal? Tbill { get { return -10 /* result.tbill ?? null*/; } }
        public decimal? Tonw { get { return level == 10 ? _invoice.tonw : null; } }
        public decimal? Torv { get { return level == 10 ? _invoice.torv : null; } }
        public decimal? Tocv { get { return level == 10 ? _invoice.tocv : null; } }
        public int? Setm { get { return level == 8 || level == 10 || level == 11 || level == 13 || _invoice.setm == 0 ? null : _invoice.setm ?? null; } }
        public decimal? Cap { get { return level == 8 || level == 10 || level == 11 || level == 13 ? null : _invoice.cap ?? null; } }
        public decimal? Insp { get { return level == 8 || level == 10 || level == 11 || level == 13 ? null : _invoice.insp ?? null; } }
        public decimal? Tvop { get { return level == 8 || level == 10 || level == 11 || level == 13 ? null : _invoice.tvop ?? null; } }
        public decimal? Tax17 { get { return level == 10 || string.IsNullOrEmpty(_invoice.seventeentax) ? null : Convert.ToDecimal(_invoice.seventeentax); } }
        public string? Tinc { get { return level == 9 && !string.IsNullOrEmpty(_invoice.tinc) ? _invoice.tinc : null; } }
        #endregion

    }
    public class PreparationBodyTaxInvoice
    {
        private readonly InvoiceItem bitem;
        private readonly int level;

        public PreparationBodyTaxInvoice(InvoiceItem bitem, int level)
        {
            this.bitem = bitem;
            this.level = level;
        }
        public string? Sstid { get { return bitem.sstid; } }
        public string? Sstt { get { return bitem.sstt; } }
        public decimal? Am { get { return level == 4 ? null : bitem.am; } }
        public string? Mu { get { return level == 4 || string.IsNullOrEmpty(bitem.mu) ? null : bitem.mu; } }
        public decimal? Nw { get { return level == 10 ? bitem.nw : null; } }
        public decimal? Fee { get { return level == 4 ? null : bitem.fee; } }
        public decimal? Cfee { get { return bitem.cfee == 0 || level == 8 || level == 10 ? null : bitem.cfee; } }
        public string? Cut { get { return level == 8 || string.IsNullOrEmpty(bitem.cut) ? null : bitem.cut; } }
        public decimal? Exr { get { return level == 8 ? null : bitem.exr; } }
        public decimal? Ssrv { get { return level == 10 ? bitem.ssrv : null; } }
        public decimal? Sscv { get { return level == 10 ? bitem.sscv : null; } }
        public decimal? Prdis { get { return level == 10 ? null : bitem.prdis; } }
        public decimal? Dis { get { return level == 10 ? null : bitem.dis; } }
        public decimal? Adis { get { return level == 10 ? null : bitem.adis; } }
        public decimal? Vra
        {
            get
            {
                return level == 14 ? 0 
                    :
                 bitem.vra;
            }
        }
        public decimal? Vam { get { return bitem.vam; } }
        public string? Odt { get { return string.IsNullOrEmpty(bitem.odt) ? null : bitem.odt; } }
        public decimal? Odr { get { return bitem.odr; } }
        public decimal? Odam { get { return bitem.odam; } }
        public string? Olt { get { return string.IsNullOrEmpty(bitem.olt) ? null : bitem.olt; } }
        public decimal? Olr { get { return bitem.olr; } }
        public decimal? Olam { get { return bitem.olam; } }
        public decimal? Consfee { get { return level == 5 || level == 13 ? bitem.consfee : null; } }
        public decimal? Spro { get { return level == 5 || level == 13 ? bitem.spro : null; } }
        public decimal? Bros { get { return level == 5 || level == 13 ? bitem.bros : null; } }
        public decimal? Tcpbs { get { return level == 5 || level == 13 ? bitem.tcpbs : null; } }
        public decimal? Cop { get { return level == 8 || level == 10 || level == 11 || level == 13 ? null : bitem.cop; } }
        public decimal? Vop { get { return level == 8 || level == 10 || level == 11 || level == 13 ? null : bitem.vop; } }
        public string? Bsrn { get { return string.IsNullOrEmpty(bitem.bsrn) ? null : bitem.bsrn; } }
        public decimal? Tsstam { get { return bitem.tsstam; } }
        public decimal? Cui { get { return level == 5 || level == 13 ? bitem.cui : null; } }
        public decimal? Cpr { get { return level == 4 && bitem.cpr.HasValue ? bitem.cpr : null; } }
        public long? Sovat { get { return level == 4 && bitem.sovat.HasValue ? bitem.sovat : null; } }

    }
}
