import re
import pdfplumber
from datetime import datetime, timedelta
from collections import defaultdict
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib import colors
import os
import locale

registos = []   # EM de ser lista

# =========================
# CONFIGURAÇÕES
# =========================
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

PDF_ENTRADA = os.path.join(BASE_DIR, "entrada.pdf")
PDF_SAIDA   = os.path.join(BASE_DIR, "saida_organizada.pdf")

OBJETIVO_DIARIO = timedelta(hours=8)

# Ajuste de idioma (se falhar, ignora)
try:
    locale.setlocale(locale.LC_TIME, "pt_PT")
except:
    pass

# =========================
# 1. EXTRAÇÃO DO PDF
# =========================

padrao = re.compile(
    r"^(\d+)\s+(.+?)\s+(\d{2}/\d{2}/\d{4})\s+(\d{2}:\d{2})"
)

with pdfplumber.open(PDF_ENTRADA) as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        if not text:
            continue

        for line in text.split("\n"):
            match = padrao.match(line.strip())
            if not match:
                continue

            registos.append({
                "id": match.group(1),
                "nome": match.group(2),
                "data": match.group(3),
                "hora": match.group(4),
            })


if not registos:
    print("Nenhum registo encontrado no PDF.")
    exit()
# =========================
# 2. AGRUPAR POR FUNCIONÁRIO
# =========================
funcionarios = defaultdict(list)
for r in registos:
    funcionarios[(r["id"], r["nome"])].append(r)

# =========================
# CABEÇALHO GERAL
# =========================
def cabecalho_geral(c, pagina):
    c.setFont("Helvetica-Bold", 14)
    c.drawString(40, 810, "Marcações por Funcionário – Completo")
    c.setFont("Helvetica", 9)
    c.drawRightString(550, 810, f"Pág. {pagina}")
    c.setStrokeColor(colors.orange)
    c.line(40, 800, 550, 800)

# =========================
# 3. GERAR PDF
# =========================
c = canvas.Canvas(PDF_SAIDA, pagesize=A4)
pagina = 1

for (id_func, nome), marcacoes in funcionarios.items():
    y = 770
    cabecalho_geral(c, pagina)

    # Bloco do funcionário
    c.setFillColor(colors.HexColor("#F2D94E"))
    c.rect(40, y - 20, 510, 20, fill=1, stroke=0)
    c.setFillColor(colors.black)

    c.setFont("Helvetica-Bold", 10)
    c.drawString(45, y - 15, f"Código: {id_func}")
    c.drawString(140, y - 15, nome)
    y -= 40

    # Cabeçalho da tabela
    c.setFont("Helvetica-Bold", 9)
    c.drawString(45, y, "Data")
    c.drawString(150, y, "Marcações")
    c.drawString(350, y, "Obj.")
    c.drawString(410, y, "Presença")
    c.drawString(490, y, "Saldo")
    c.line(40, y - 2, 550, y - 2)
    y -= 15

    # =========================
    # AGRUPAR POR SEMANA → DIA
    # =========================
    por_semana = defaultdict(lambda: defaultdict(list))

    for m in marcacoes:
        data_dt = datetime.strptime(m["data"], "%m/%d/%Y")
        ano, semana, _ = data_dt.isocalendar()
        por_semana[(ano, semana)][data_dt].append(m["hora"])

    # =========================
    # IMPRIMIR SEMANAS
    # =========================
    for (ano, semana), dias in sorted(por_semana.items()):
        datas = sorted(dias.keys())
        inicio = datas[0].strftime("%d/%m/%Y")
        fim = datas[-1].strftime("%d/%m/%Y")

        if y < 120:
            c.showPage()
            pagina += 1
            y = 770
            cabecalho_geral(c, pagina)

        # Título da semana
        c.setFont("Helvetica-Bold", 10)
        c.setFillColor(colors.darkblue)
        c.drawString(45, y, f"SEMANA {inicio} – {fim}")
        c.setFillColor(colors.black)
        y -= 12

        c.setStrokeColor(colors.grey)
        c.line(45, y, 550, y)
        y -= 10

        # Dias da semana
        for data_dt in datas:
            if y < 80:
                c.showPage()
                pagina += 1
                y = 770
                cabecalho_geral(c, pagina)

            horas_raw = dias[data_dt]
            horas = sorted(datetime.strptime(h, "%H:%M") for h in horas_raw)

            # Calcular presença
            total = timedelta()
            for i in range(0, len(horas) - 1, 2):
                total += horas[i + 1] - horas[i]

            saldo = total - OBJETIVO_DIARIO

            # Cor do saldo
            if saldo.total_seconds() < 0:
                cor = colors.red
                sinal = "-"
            elif saldo.total_seconds() > 0:
                cor = colors.blue
                sinal = "+"
            else:
                cor = colors.black
                sinal = ""

            data_str = data_dt.strftime("%d-%m-%y - %A")

            pres_h = total.seconds // 3600
            pres_m = (total.seconds % 3600) // 60

            s = abs(saldo)
            s_h = s.seconds // 3600
            s_m = (s.seconds % 3600) // 60

            # Linha do dia
            c.setFont("Helvetica", 9)
            c.drawString(45, y, data_str)
            c.drawString(150, y, "  ".join(h.strftime("%H:%M") for h in horas))
            c.drawString(350, y, "08:00")
            c.drawString(410, y, f"{pres_h:02d}:{pres_m:02d}")

            c.setFillColor(cor)
            c.drawString(490, y, f"{sinal}{s_h:02d}:{s_m:02d}")
            c.setFillColor(colors.black)

            y -= 14

        y -= 10  # espaço entre semanas

    c.showPage()
    pagina += 1

c.save()

print("PDF gerado com sucesso (organizado por semanas):")
print(os.path.abspath(PDF_SAIDA))
