package org.fuseri.modulecertificate.certificate;

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import jakarta.servlet.http.HttpServletResponse;
import org.fuseri.model.dto.certificate.CertificateCreateDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.util.List;

@Service
public class CertificateService {

    private final CertificateRepository certificateRepository;

    @Autowired
    public CertificateService(CertificateRepository certificateRepository) {
        this.certificateRepository = certificateRepository;
    }

    @Transactional(readOnly = true)
    public Certificate findById(Long id) {
        return certificateRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Certificate with id: " + id + " was not found."));
    }

    @Transactional(readOnly = true)
    public List<Certificate> findByUserId(Long userId) {
        return certificateRepository.findCertificateByUserId(userId);
    }

    @Transactional(readOnly = true)
    public List<Certificate> findByUserIdAndCourseId(Long userId, Long courseId) {
        return certificateRepository.findCertificateByUserIdAndCourseId(userId, courseId);
    }

    @Transactional(readOnly = true)
    public Certificate save(Certificate certificate) {
        return certificateRepository.save(certificate);
    }

    public void generateCertificateFile(CertificateCreateDto certificateCreateDto, String filename, HttpServletResponse response) throws IOException {
        response.setContentType("application/octet-stream");
        String headerKey = "Content-Disposition";

        String headerValue = "attachment; filename=" + filename;
        response.setHeader(headerKey, headerValue);

        PdfWriter writer = new PdfWriter(response.getOutputStream());
        PdfDocument pdfDoc = new PdfDocument(writer);
        pdfDoc.addNewPage();
        Document document = new Document(pdfDoc);
        String content = "FUSERI LANGUAGE SCHOOL";
        Paragraph paragraph = new Paragraph(content);
        paragraph.setFontSize(22);
        paragraph.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraph);

        content = "CERTIFICATE";
        paragraph = new Paragraph(content);
        paragraph.setFontSize(72);
        paragraph.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraph);

        content = certificateCreateDto.getUser().getFirstName() + " " + certificateCreateDto.getUser().getLastName();
        paragraph = new Paragraph(content);
        paragraph.setFontSize(34);
        paragraph.setFontColor(ColorConstants.BLUE);
        paragraph.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraph);

        content = certificateCreateDto.getCourse().getProficiency().toString();
        paragraph = new Paragraph(content);
        paragraph.setFontSize(54);
        paragraph.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraph);

        content = "Congratulations on passing " + certificateCreateDto.getCourse().getLanguage().toString().toLowerCase() + " course " + certificateCreateDto.getCourse().getName().toUpperCase() + ".";
        paragraph = new Paragraph(content);
        paragraph.setFontSize(22);
        paragraph.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraph);

        document.close();
        pdfDoc.close();
        writer.close();
    }

    public String generateCertificateFileName(CertificateCreateDto certificateCreateDto) {
        var fileName = certificateCreateDto.getCourse().getName() +
                certificateCreateDto.getUser().getUsername() + ".pdf";
        return fileName.replace(" ", "_");
    }

    @Transactional(readOnly = true)
    public void delete(Long certificateId) {
        certificateRepository.deleteById(certificateId);
    }

    @Transactional(readOnly = true)
    public Page<Certificate> findAll(Pageable pageable) {
        return certificateRepository.findAll(pageable);
    }
}

