import { Document, Page, StyleSheet, Text, View } from '@react-pdf/renderer';
import { EMITTENTE } from '@/config/emittente';
import {
  capitalizza, euro, formattaData, numeroDocumento, numeroIt, percentuale,
  totaleDocumento, totaleImponibile, totaleOnorario,
} from '@/lib/calcoli';
import { registraFont } from '@/lib/fonts';
import {
  descrizioneCassa, descrizioneModalitaPagamento, descrizioneNatura, etichettaTipoDocumento,
} from '@/lib/mappe';
import type { Fattura, Soggetto } from '@/lib/tipi';

const ETICHETTA = '#828282';
const TESTO = '#6a6a6a';
const BORDO = '#cecece';
const RIGA_ALTERNATA = '#ededed';

const stili = StyleSheet.create({
  pagina: {
    fontFamily: 'Trebuchet',
    fontSize: 9,
    color: TESTO,
    paddingTop: 30,
    paddingHorizontal: 28.3,
    paddingBottom: 65.3,
  },
  bold: { fontWeight: 'bold' },

  header: { textAlign: 'right', color: ETICHETTA, fontSize: 8.25 },
  headerFattura: { fontSize: 10.5, marginTop: 10 },
  separatoreHeader: { borderBottomWidth: 0.75, borderBottomColor: BORDO, marginTop: 46 },

  contraenti: { flexDirection: 'row', marginTop: 9 },
  contraentiSx: { flex: 1 },
  contraentiDx: { width: 255 },
  etichettaMedia: { fontSize: 6.75, color: ETICHETTA, marginBottom: 3 },
  rigaAnagrafica: { marginBottom: 2.5 },

  tabella: { marginTop: 36, borderBottomWidth: 0.75, borderBottomColor: BORDO },
  rigaTabella: { flexDirection: 'row' },
  intestazioneTabella: {
    borderTopWidth: 0.75,
    borderBottomWidth: 0.75,
    borderColor: BORDO,
    fontSize: 6,
    color: ETICHETTA,
  },
  cellaDescrizione: { width: 453.9, paddingVertical: 6, paddingLeft: 7.5, paddingRight: 10 },
  cellaImporto: {
    width: 57.8,
    borderLeftWidth: 0.75,
    borderLeftColor: BORDO,
    paddingVertical: 6,
    paddingRight: 6.4,
    textAlign: 'right',
  },
  cellaIva: {
    width: 26.9,
    borderLeftWidth: 0.75,
    borderLeftColor: BORDO,
    paddingVertical: 6,
    textAlign: 'center',
  },
  cellaIntestazione: { paddingVertical: 4.5, fontWeight: 'bold' },

  note: { marginTop: 18 },
  testoNote: { marginTop: 3 },

  spaziatore: { flexGrow: 1 },

  bloccoBasso: { borderTopWidth: 0.59, borderBottomWidth: 0.59, borderColor: BORDO, fontSize: 6.53 },
  rigaBassa: { flexDirection: 'row' },
  separatoreBasso: { borderTopWidth: 0.59, borderTopColor: BORDO },
  cellaBassaSx: {
    width: 256.2,
    borderRightWidth: 0.59,
    borderRightColor: BORDO,
    paddingTop: 10,
    paddingBottom: 7,
    paddingRight: 10,
  },
  cellaBassaDx: { flex: 1, paddingTop: 10, paddingBottom: 7, paddingLeft: 9 },
  quadranteAlto: { minHeight: 75 },
  quadranteBasso: { minHeight: 112 },
  totaliInFondo: { justifyContent: 'flex-end' },
  etichettaBassa: { fontSize: 5.34, color: ETICHETTA, marginBottom: 3 },
  rigaPagamento: { marginBottom: 1.5 },

  rigaRiepilogo: { flexDirection: 'row', marginBottom: 3 },
  riepilogoDescrizione: { flex: 1, fontStyle: 'italic', paddingRight: 6 },
  riepilogoImponibile: { width: 55, textAlign: 'right' },
  riepilogoImposta: { width: 32, textAlign: 'right' },

  rigaTotale: { flexDirection: 'row', justifyContent: 'flex-end', marginBottom: 2.5 },
  etichettaTotale: { flex: 1, textAlign: 'right' },
  valoreTotale: { width: 44, textAlign: 'right' },
  totaleGrande: {
    fontSize: 17.81,
    fontWeight: 'bold',
    color: ETICHETTA,
    textAlign: 'right',
    marginTop: 5,
  },

  piede: {
    position: 'absolute',
    bottom: 15,
    left: 28.3,
    right: 28.3,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'flex-end',
    fontSize: 7.5,
    color: ETICHETTA,
  },
  piedeDx: { textAlign: 'right' },
  piedeSx: { marginBottom: 4.5 },
});

function indirizzoEmittente(s: Soggetto): string {
  const via = [capitalizza(s.indirizzo), s.civico].filter(Boolean).join(' ');
  const provincia = s.provincia ? ` (${s.provincia})` : '';
  return `${via} - ${s.cap} - ${capitalizza(s.comune)}${provincia}`;
}

function PaginaFattura({ f }: { f: Fattura }) {
  const etichettaDoc = etichettaTipoDocumento(f.tipoDocumento);
  const numDoc = numeroDocumento(f.numero, f.dataIso);
  const dataDoc = formattaData(f.dataIso);
  const nomeEmittente = `${EMITTENTE.titolo} ${capitalizza(f.emittente.denominazione)}`;
  const pagamento = f.pagamenti[0];

  const righe = [
    ...f.linee.map((l) => ({
      descrizione: l.descrizione,
      importo: euro(l.prezzoTotaleCent),
      aliquota: percentuale(l.aliquotaIva),
    })),
    ...(f.bolloCent != null
      ? [{ descrizione: 'Marca da bollo', importo: euro(f.bolloCent), aliquota: '0' }]
      : []),
  ];

  const righeRiepilogo = [
    ...f.riepiloghi.map((r) => ({
      descrizione: r.natura
        ? `${percentuale(r.aliquotaIva)}% - ${descrizioneNatura(r.natura, f.regimeFiscale)}`
        : `${percentuale(r.aliquotaIva)}%`,
      imponibile: numeroIt(r.imponibileCent),
      imposta: euro(r.impostaCent),
    })),
    ...(f.bolloCent != null
      ? [{ descrizione: '0% - Escluso Art.15', imponibile: numeroIt(f.bolloCent), imposta: euro(0) }]
      : []),
  ];

  const totali: Array<[string, string]> = [
    ['Totale onorario', euro(totaleOnorario(f))],
    ...f.casse.map(
      (c): [string, string] => [
        `${descrizioneCassa(c.tipo)} ${percentuale(c.aliquota)}%`,
        euro(c.importoCent),
      ],
    ),
    ['Imponibile', euro(totaleImponibile(f))],
    ...(f.bolloCent != null
      ? ([
          ['Non imponibile', euro(f.bolloCent)],
          ['Marca da bollo', euro(f.bolloCent)],
        ] as Array<[string, string]>)
      : []),
  ];

  return (
    <Page size="A4" style={stili.pagina} wrap>
      <View style={stili.header}>
        <Text style={stili.bold}>{nomeEmittente}</Text>
        <Text>{indirizzoEmittente(f.emittente)}</Text>
        <Text>
          P.iva {f.emittente.partitaIva} - C.F. {f.emittente.codiceFiscale}
        </Text>
        <Text style={stili.headerFattura}>
          <Text style={stili.bold}>{etichettaDoc}</Text> nr.{' '}
          <Text style={stili.bold}>{numDoc}</Text> del <Text style={stili.bold}>{dataDoc}</Text>
        </Text>
      </View>

      <View style={stili.separatoreHeader} />

      <View style={stili.contraenti}>
        <View style={stili.contraentiSx}>
          {f.destinatario.partitaIva && (
            <Text style={stili.rigaAnagrafica}>
              <Text style={stili.bold}>P.IVA</Text> {f.destinatario.partitaIva}
            </Text>
          )}
          {f.destinatario.codiceFiscale && (
            <Text style={stili.rigaAnagrafica}>
              <Text style={stili.bold}>CF</Text> {f.destinatario.codiceFiscale}
            </Text>
          )}
          {f.destinatario.email && (
            <Text style={stili.rigaAnagrafica}>
              <Text style={stili.bold}>EMAIL</Text> {f.destinatario.email}
            </Text>
          )}
        </View>
        <View style={stili.contraentiDx}>
          <Text style={stili.etichettaMedia}>DESTINATARIO</Text>
          <Text style={[stili.rigaAnagrafica, stili.bold]}>{f.destinatario.denominazione}</Text>
          <Text style={stili.rigaAnagrafica}>
            {[f.destinatario.indirizzo, f.destinatario.civico].filter(Boolean).join(', ')}
          </Text>
          <Text>
            {f.destinatario.cap} {f.destinatario.comune}
            {f.destinatario.provincia ? ` (${f.destinatario.provincia})` : ''}
          </Text>
        </View>
      </View>

      <View style={stili.tabella}>
        <View style={[stili.rigaTabella, stili.intestazioneTabella]}>
          <Text style={[stili.cellaDescrizione, stili.cellaIntestazione]}>DESCRIZIONE</Text>
          <Text style={[stili.cellaImporto, stili.cellaIntestazione]}>IMPORTO</Text>
          <Text style={[stili.cellaIva, stili.cellaIntestazione]}>% IVA</Text>
        </View>
        {righe.map((r, i) => (
          <View
            key={i}
            style={[stili.rigaTabella, i % 2 === 0 ? { backgroundColor: RIGA_ALTERNATA } : {}]}
            wrap={false}
          >
            <Text style={stili.cellaDescrizione}>{r.descrizione}</Text>
            <Text style={stili.cellaImporto}>{r.importo}</Text>
            <Text style={stili.cellaIva}>{r.aliquota}</Text>
          </View>
        ))}
      </View>

      <View style={stili.note}>
        <Text style={stili.etichettaMedia}>NOTE</Text>
        <Text style={stili.testoNote}>{EMITTENTE.note}</Text>
      </View>

      <View style={stili.spaziatore} />

      <View style={stili.bloccoBasso} wrap={false}>
        <View style={stili.rigaBassa}>
          <View style={[stili.cellaBassaSx, stili.quadranteAlto]}>
            {pagamento && (
              <>
                <Text style={stili.etichettaBassa}>MODALITÀ DI PAGAMENTO</Text>
                {pagamento.modalita && (
                  <Text style={[stili.rigaPagamento, stili.bold]}>
                    {descrizioneModalitaPagamento(pagamento.modalita)}
                  </Text>
                )}
                {pagamento.iban && (
                  <Text style={stili.rigaPagamento}>
                    IBAN: <Text style={stili.bold}>{pagamento.iban}</Text>
                  </Text>
                )}
                {pagamento.beneficiario && (
                  <Text style={[stili.rigaPagamento, stili.bold]}>{pagamento.beneficiario}</Text>
                )}
              </>
            )}
          </View>
          <View style={[stili.cellaBassaDx, stili.quadranteAlto]}>
            {f.pagamenti.length > 0 && (
              <>
                <Text style={stili.etichettaBassa}>SCADENZE</Text>
                {f.pagamenti.map((p, i) => (
                  <Text key={i} style={stili.rigaPagamento}>
                    <Text style={stili.bold}>{p.dataIso ? `${formattaData(p.dataIso)}:` : ''}</Text>{' '}
                    {euro(p.importoCent)}
                  </Text>
                ))}
              </>
            )}
          </View>
        </View>
        <View style={[stili.rigaBassa, stili.separatoreBasso]}>
          <View style={[stili.cellaBassaSx, stili.quadranteBasso]}>
            {righeRiepilogo.length > 0 && (
              <>
                <View style={stili.rigaRiepilogo}>
                  <Text style={[stili.etichettaBassa, { flex: 1 }]}>RIEPILOGO IVA</Text>
                  <Text style={[stili.etichettaBassa, stili.riepilogoImponibile]}>IMPONIBILE</Text>
                  <Text style={[stili.etichettaBassa, stili.riepilogoImposta]}>IMPOSTE</Text>
                </View>
                {righeRiepilogo.map((r, i) => (
                  <View key={i} style={stili.rigaRiepilogo}>
                    <Text style={stili.riepilogoDescrizione}>{r.descrizione}</Text>
                    <Text style={stili.riepilogoImponibile}>{r.imponibile}</Text>
                    <Text style={stili.riepilogoImposta}>{r.imposta}</Text>
                  </View>
                ))}
              </>
            )}
          </View>
          <View style={[stili.cellaBassaDx, stili.quadranteBasso, stili.totaliInFondo]}>
            {totali.map(([etichetta, valore], i) => (
              <View key={i} style={stili.rigaTotale}>
                <Text style={stili.etichettaTotale}>{etichetta}</Text>
                <Text style={stili.valoreTotale}>{valore}</Text>
              </View>
            ))}
            <Text style={stili.totaleGrande}>{euro(totaleDocumento(f))}</Text>
          </View>
        </View>
      </View>

      <View style={stili.piede} fixed>
        <Text
          style={stili.piedeSx}
          render={({ pageNumber, totalPages }) =>
            `Fattura nr. ${numDoc} del ${dataDoc} - ${pageNumber} / ${totalPages}`
          }
        />
        <View style={stili.piedeDx}>
          <Text>
            <Text style={stili.bold}>{nomeEmittente}</Text> {EMITTENTE.email}
          </Text>
          <Text>cell: {EMITTENTE.cellulare}</Text>
        </View>
      </View>
    </Page>
  );
}

export function FatturaPDF({ fatture }: { fatture: Fattura[] }) {
  registraFont();
  return (
    <Document>
      {fatture.map((f, i) => (
        <PaginaFattura key={i} f={f} />
      ))}
    </Document>
  );
}
