package fr.titionfire;

import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.*;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Main {
    public static void main(String[] args) {

        File dest = new File(args[0]);

        if (args[1].equals("membre")) {
            PdfData pdfData = new PdfData();
            pdfData.fname = args[2];
            pdfData.lname = args[3];
            pdfData.genre = args[4];
            pdfData.categorie = args[5];
            pdfData.certificate = args[6];
            pdfData.saison = Integer.parseInt(args[7]);
            pdfData.licence = Integer.parseInt(args[8]);
            pdfData.club = args[9];
            pdfData.club_no = args[10].equals("null") ? -1 : Integer.parseInt(args[10]);
            pdfData.birth_date = args[11];
            pdfData.photo_file = new File(args[12]);

            try {
                FileOutputStream out = new FileOutputStream(dest);
                new Main().make_pdf(pdfData, out);
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(1);
            }
        } else {
            PdfDataClub pdfData = new PdfDataClub();
            pdfData.name = args[2];
            pdfData.saison = Integer.parseInt(args[3]);
            pdfData.club_no = Integer.parseInt(args[4]);
            pdfData.sign_file = new File(args[5]);

            try {
                FileOutputStream out = new FileOutputStream(dest);
                new Main().make_pdf_club(pdfData, out);
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(1);
            }
        }

        System.out.println("PDF generated successfully");
        System.exit(0);
    }

    public static class BorderEvent implements PdfPTableEvent {
        public void tableLayout(PdfPTable table, float[][] widths,
                                float[] heights, int headerRows, int rowStart,
                                PdfContentByte[] canvases) {
            float[] width = widths[0];
            float x1 = width[0];
            float x2 = width[width.length - 1];
            float y1 = heights[0];
            float y2 = heights[heights.length - 1];
            PdfContentByte cb = canvases[PdfPTable.LINECANVAS];
            cb.setLineWidth(3);
            cb.rectangle(x1, y1, x2 - x1, y2 - y1);
            cb.stroke();

            cb.setLineWidth(1);
            cb.rectangle(x1 + 4, y1 - 4, x2 - x1 - 8, y2 - y1 + 8);
            cb.stroke();

            cb.resetRGBColorStroke();
        }
    }

    private void make_pdf_club(PdfDataClub pdfData, FileOutputStream out) throws IOException {
        Document document = new Document(PageSize.A4.rotate());
        PdfWriter.getInstance(document, out);
        document.open();

        document.addCreator("FFSAF");
        document.addTitle(
                "Attestation d'affiliation " + pdfData.saison + "-" + (pdfData.saison + 1) + " - " + pdfData.name);
        document.addCreationDate();
        document.addProducer("https://www.ffsaf.fr");

        InputStream fontStream = Main.class.getClassLoader().getResourceAsStream("Helvetica.ttf");
        if (fontStream == null)
            throw new IOException("Font file not found");
        BaseFont customFont = BaseFont.createFont("Helvetica.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true,
                null, fontStream.readAllBytes());

        InputStream fontStream2 = Main.class.getClassLoader().getResourceAsStream("Helvetica-Bold.ttf");
        if (fontStream2 == null)
            throw new IOException("Font file not found");
        BaseFont customFontBold = BaseFont.createFont("Helvetica-Bold.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true,
                null, fontStream2.readAllBytes());

        InputStream fontStream3 = Main.class.getClassLoader().getResourceAsStream("helvetica-light.ttf");
        if (fontStream3 == null)
            throw new IOException("Font file not found");
        BaseFont customFontLight = BaseFont.createFont("helvetica-light.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true,
                null, fontStream3.readAllBytes());

        // Creating the main table
        PdfPTable mainTable = new PdfPTable(1);
        mainTable.setWidthPercentage(100);
        mainTable.setSpacingBefore(0f);
        mainTable.setSpacingAfter(0f);
        mainTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
        mainTable.setExtendLastRow(true);

        mainTable.setTableEvent(new BorderEvent());

        // Creating the main table
        PdfPTable headerRow = new PdfPTable(2);
        headerRow.setWidths(new float[]{1, 2});
        headerRow.getDefaultCell().setBorder(PdfPCell.NO_BORDER);

        // Adding logo
        Image logo = Image.getInstance(
                Objects.requireNonNull(
                        getClass().getClassLoader().getResource("Logo-FFSAF-2023.png")));
        logo.scaleToFit(160, 160);
        PdfPCell logoCell = new PdfPCell(logo);
        logoCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        logoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        logoCell.setPadding(0);
        logoCell.setRowspan(1);
        logoCell.setPaddingTop(20);
        logoCell.setPaddingBottom(20);
        logoCell.setBorder(PdfPCell.NO_BORDER);
        headerRow.addCell(logoCell);

        List<Paragraph> pList = new ArrayList<>();
        pList.add(new Paragraph("Fédération", new Font(customFontBold, 16, Font.NORMAL)));
        pList.add(new Paragraph("FRANCE SOFT ARMORED FIGHTING", new Font(customFontBold, 18, Font.NORMAL)));
        pList.add(new Paragraph("Association loi 1901 n° W633001595\n ", new Font(customFontLight, 11, Font.NORMAL)));
        pList.add(new Paragraph("5 place de la Barreyre", new Font(customFont, 11, Font.NORMAL)));
        pList.add(new Paragraph("63320 Champeix\n ", new Font(customFont, 11, Font.NORMAL)));
        pList.add(new Paragraph("ffsaf.fr", new Font(customFontBold, 14, Font.NORMAL)));

        PdfPCell headerCell = new PdfPCell();
        pList.forEach(p -> p.setAlignment(Element.ALIGN_CENTER));
        pList.forEach(headerCell::addElement);
        headerCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        headerCell.setBorder(PdfPCell.NO_BORDER);
        headerRow.addCell(headerCell);
        mainTable.addCell(headerRow);

        pList.clear();
        pList.add(new Paragraph("CLUB AFFILIÉ SAISON " + pdfData.saison + "-" + (pdfData.saison + 1) + "\n ",
                new Font(customFontBold, 24, Font.NORMAL)));
        pList.add(new Paragraph(pdfData.name, new Font(customFontBold, 20, Font.NORMAL, new Color(0, 112, 192))));
        pList.add(new Paragraph(String.format("- association n°%05d -\n ", pdfData.club_no),
                new Font(customFont, 18, Font.TIMES_ROMAN)));

        PdfPCell bodyCell = new PdfPCell();
        pList.forEach(p -> p.setAlignment(Element.ALIGN_CENTER));
        pList.forEach(bodyCell::addElement);
        bodyCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        bodyCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        bodyCell.setBorder(PdfPCell.NO_BORDER);
        mainTable.addCell(bodyCell);

        PdfPTable footerRow = new PdfPTable(2);
        footerRow.setWidths(new float[]{2, 1});
        footerRow.getDefaultCell().setBorder(PdfPCell.NO_BORDER);


        PdfPTable footerSubRow = new PdfPTable(2);
        footerSubRow.setWidths(new float[]{1, 5});
        footerSubRow.getDefaultCell().setBorder(PdfPCell.NO_BORDER);

        Image logo2 = Image.getInstance(
                Objects.requireNonNull(
                        getClass().getClassLoader().getResource("safef.jpg")));
        logo2.scaleToFit(65, 65);
        PdfPCell logo2Cell = new PdfPCell(logo2);
        logo2Cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        logo2Cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        logo2Cell.setPadding(0);
        logo2Cell.setRowspan(1);
        logo2Cell.setPaddingLeft(7);
        logo2Cell.setBorder(PdfPCell.NO_BORDER);
        footerSubRow.addCell(logo2Cell);

        pList.clear();
        pList.add(new Paragraph("La FFSAF est fondatrice et affilié à la SAFE Federation.",
                new Font(customFontBold, 10, Font.NORMAL)));
        pList.add(new Paragraph("Soft Armored Fighting European Federation",
                new Font(customFontLight, 10, Font.TIMES_ROMAN)));

        PdfPCell footerCell = new PdfPCell();
        pList.forEach(p -> p.setAlignment(Element.ALIGN_LEFT));
        pList.forEach(footerCell::addElement);
        footerCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        footerCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        footerCell.setBorder(PdfPCell.NO_BORDER);
        footerSubRow.addCell(footerCell);
        footerRow.addCell(footerSubRow);

        pList.clear();
        pList.add(new Paragraph("Le président de la FFSAF,", new Font(customFont, 13, Font.NORMAL)));
        pList.add(new Paragraph("Guillaume Andrieux", new Font(customFontBold, 13, Font.NORMAL)));

        PdfPCell footerCell2 = new PdfPCell();
        pList.forEach(p -> p.setAlignment(Element.ALIGN_LEFT));
        pList.forEach(footerCell2::addElement);

        Image sign = Image.getInstance(Files.readAllBytes(pdfData.sign_file.toPath()));
        sign.scaleToFit(120, 60);
        sign.setSpacingBefore(10);
        footerCell2.addElement(sign);

        footerCell2.setHorizontalAlignment(Element.ALIGN_LEFT);
        footerCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
        footerCell2.setBorder(PdfPCell.NO_BORDER);
        footerRow.addCell(footerCell2);

        mainTable.addCell(footerRow);
        document.add(mainTable);

        // Close the document
        document.close();
    }

    private void make_pdf(PdfData pdfData, FileOutputStream out) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        Document document = new Document();
        PdfWriter.getInstance(document, out);
        document.open();

        document.addCreator("FFSAF");
        document.addTitle(
                "Attestation d'adhésion " + pdfData.saison + "-" + (pdfData.saison + 1) + " de " + pdfData.lname + " " + pdfData.fname);
        document.addCreationDate();
        document.addProducer("https://www.ffsaf.fr");

        InputStream fontStream = Main.class.getClassLoader().getResourceAsStream("DMSans-Regular.ttf");
        if (fontStream == null) {
            throw new IOException("Font file not found");
        }
        BaseFont customFont = BaseFont.createFont("DMSans-Regular.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, true,
                null, fontStream.readAllBytes());

        // Adding font
        Font headerFont = new Font(customFont, 26, Font.BOLD);
        Font subHeaderFont = new Font(customFont, 16, Font.BOLD);
        Font bigFont = new Font(customFont, 18, Font.BOLD);
        Font bodyFont = new Font(customFont, 15, Font.BOLD);
        Font smallFont = new Font(customFont, 10, Font.NORMAL);

        // Creating the main table
        PdfPTable mainTable = new PdfPTable(2);
        mainTable.setWidthPercentage(100);
        mainTable.setSpacingBefore(20f);
        mainTable.setSpacingAfter(0f);
        mainTable.setWidths(new float[]{120, 300});
        mainTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);

        // Adding logo
        Image logo = Image.getInstance(
                Objects.requireNonNull(
                        getClass().getClassLoader().getResource("Logo-FFSAF-2023.png")));
        logo.scaleToFit(120, 120);
        PdfPCell logoCell = new PdfPCell(logo);
        logoCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        logoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        logoCell.setPadding(0);
        logoCell.setRowspan(1);
        logoCell.setBorder(PdfPCell.NO_BORDER);
        mainTable.addCell(logoCell);

        // Adding header
        PdfPCell headerCell = new PdfPCell(new Phrase("FEDERATION FRANCE\nSOFT ARMORED FIGHTING", headerFont));
        headerCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        headerCell.setBorder(PdfPCell.NO_BORDER);
        mainTable.addCell(headerCell);

        document.add(mainTable);

        Paragraph addr = new Paragraph("5 place de la Barreyre\n63320 Champeix", subHeaderFont);
        addr.setAlignment(Element.ALIGN_CENTER);
        addr.setSpacingAfter(2f);
        document.add(addr);

        Paragraph association = new Paragraph("Association loi 1901 W633001595\nSIRET 829 458 355 00015", smallFont);
        association.setAlignment(Element.ALIGN_CENTER);
        document.add(association);

        // Adding spacing
        document.add(new Paragraph("\n\n"));

        // Adding attestation
        PdfPTable attestationTable = new PdfPTable(1);
        attestationTable.setWidthPercentage(60);
        PdfPCell attestationCell = new PdfPCell(
                new Phrase("ATTESTATION D'ADHESION\nSaison " + pdfData.saison + "-" + (pdfData.saison + 1),
                        bigFont));
        attestationCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        attestationCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        attestationCell.setPadding(20f);
        attestationTable.addCell(attestationCell);
        document.add(attestationTable);

        // Adding spacing
        document.add(new Paragraph("\n\n"));

        // Adding member details table
        PdfPTable memberTable = new PdfPTable(2);
        memberTable.setWidthPercentage(100);
        memberTable.setWidths(new float[]{130, 300});
        memberTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);

        // Adding member photo
        Image memberPhoto;
        if (pdfData.photo_file != null && pdfData.photo_file.exists() && !pdfData.photo_file.getAbsolutePath()
                .equals("/dev/null")) {
            memberPhoto = Image.getInstance(Files.readAllBytes(pdfData.photo_file.toPath()));
        } else {
            memberPhoto = Image.getInstance(
                    Objects.requireNonNull(getClass().getClassLoader().getResource("blank-profile-picture.png")));
        }
        memberPhoto.scaleToFit(120, 150);
        PdfPCell photoCell = new PdfPCell(memberPhoto);
        photoCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        photoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        photoCell.setRowspan(5);
        photoCell.setBorder(PdfPCell.NO_BORDER);
        memberTable.addCell(photoCell);

        String[] cert;
        if (pdfData.certificate != null && !pdfData.certificate.isBlank()) {
            cert = pdfData.certificate.split("¤");
            if (cert.length <= 1) {
                cert = new String[]{pdfData.certificate, "--"};
            } else {
                try {
                    cert[1] = sdf.format(new SimpleDateFormat("yyyy-MM-dd").parse(cert[1]));
                } catch (ParseException e) {
                    cert[1] = "--";
                }
            }
        } else {
            cert = new String[]{"--", "--"};
        }

        // Adding member details
        memberTable.addCell(new Phrase("NOM : " + pdfData.lname.toUpperCase(), bodyFont));
        memberTable.addCell(new Phrase("Prénom : " + pdfData.fname, bodyFont));
        memberTable.addCell(new Phrase(String.format("Licence n° : %05d", pdfData.licence), bodyFont));
        memberTable.addCell(new Phrase("Certificat médical par " + cert[0] + ", le " + cert[1], bodyFont));
        memberTable.addCell(new Phrase("")); // Empty cell for spacing

        document.add(memberTable);

        // Adding spacing
        document.add(new Paragraph("\n"));

        Paragraph memberClub = new Paragraph("CLUB : " + pdfData.club.toUpperCase(), bodyFont);
        document.add(memberClub);

        Paragraph memberClubNumber = new Paragraph(String.format("N° club : %05d ", pdfData.club_no), bodyFont);
        document.add(memberClubNumber);

        // Adding spacing
        document.add(new Paragraph("\n"));

        Paragraph memberBirthdate = new Paragraph("Date de naissance : " + pdfData.birth_date, bodyFont);
        document.add(memberBirthdate);

        Paragraph memberGender = new Paragraph("Sexe : " + pdfData.genre, bodyFont);
        document.add(memberGender);

        Paragraph memberAgeCategory = new Paragraph("Catégorie d'âge : " + pdfData.categorie, bodyFont);
        document.add(memberAgeCategory);

        // Adding spacing
        document.add(new Paragraph("\n\n"));

        // Adding attestation text
        PdfPTable textTable = new PdfPTable(1);
        textTable.setWidthPercentage(100);
        PdfPCell textCell = new PdfPCell(new Phrase(
                """
                        Ce document atteste que l’adhérent
                        - est valablement enregistré auprès de la FFSAF,
                        - est assuré dans sa pratique du Béhourd Léger et du Battle Arc en entraînement et en compétition.
                        
                        Il peut donc s’inscrire à tout tournoi organisé sous l’égide de la FFSAF s’il remplit les éventuelles
                        conditions de qualification.
                        Il peut participer à tout entraînement dans un club affilié si celui ci autorise les visiteurs.""",
                smallFont));
        textCell.setHorizontalAlignment(Element.ALIGN_LEFT);
        textCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        textCell.setBorder(PdfPCell.NO_BORDER);
        textTable.addCell(textCell);
        document.add(textTable);

        // Close the document
        document.close();
    }
}