import firebirdsql as fdb
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter
from datetime import datetime
import os
import sys

# --- Připojení ---
conn = fdb.connect(
    host='192.168.1.10',
    port=3050,
    database=r'm:\Medicus\data\MEDICUS.FDB',
    user='SYSDBA', password='masterkey', charset='WIN1250'
)
cur = conn.cursor()

# --- Výstupní soubor ---
output_dir = r'z:\Dropbox\Ordinace\Reporty'
now = datetime.now()
filename = now.strftime('%Y-%m-%d %H-%M-%S') + ' faktury.xlsx'
output_path = os.path.join(output_dir, filename)

# --- Smazání předchozích verzí ---
for f in os.listdir(output_dir):
    if f.endswith(' faktury.xlsx'):
        os.remove(os.path.join(output_dir, f))

wb = openpyxl.Workbook()

# =====================
# Pomocné funkce
# =====================

HEADER_FILL = PatternFill('solid', fgColor='2F5496')
HEADER_FONT = Font(bold=True, color='FFFFFF')
LINK_FONT = Font(color='0563C1', underline='single')
ZEBRA_FILL = PatternFill('solid', fgColor='DCE6F1')

def style_header(ws):
    for cell in ws[1]:
        cell.fill = HEADER_FILL
        cell.font = HEADER_FONT
        cell.alignment = Alignment(horizontal='center')

def autofit(ws):
    for col in ws.columns:
        max_len = max((len(str(cell.value)) if cell.value is not None else 0) for cell in col)
        ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 2, 40)

def fmt(val):
    if val is None:
        return ''
    return val

# =====================
# List 1 – FAK
# =====================

ws1 = wb.active
ws1.title = 'FAK'

cur.execute('''
    SELECT
        ID, CISFAK, POJ, DATUMOD, DATUMDO, DATVYS, DATODE,
        VYKONY, KAPITACE, ZALOHA, CENA, ZAPLACENO, ZUM, HOSPAUSAL,
        PROPLACENO, SPLAT, DRUH, TYP, ROK, OBDOB,
        NAZFAK, POZFAK, OBDFAK,
        ICO, BANKA, UCET,
        ODJMENO, ODULICE, ODMISTO, ODPSC,
        PLNAZEV, PLULICE, PLMISTO, PLPSC,
        ICZ, ICZ1, IDICZ, PORCISLO, DRUHPOJ, POZNAMKA
    FROM FAK
    ORDER BY ID DESC
''')
fak_cols = [d[0] for d in cur.description]
fak_rows = cur.fetchall()

ws1.append(fak_cols)
for i, row in enumerate(fak_rows, start=2):
    ws1.append([fmt(v) for v in row])
    if i % 2 == 0:
        for cell in ws1[i]:
            cell.fill = ZEBRA_FILL

style_header(ws1)
ws1.freeze_panes = 'A2'
autofit(ws1)

# =====================
# List 2 – FAKDET
# =====================

ws2 = wb.create_sheet('FAKDET')

cur.execute('''
    SELECT
        fd.ID, fd.IDFAK,
        f.CISFAK, f.POJ, f.DATUMOD, f.DATUMDO, f.ROK,
        fd.ICP, fd.ODB, fd.IDUZI,
        u.PRIJMENI, u.JMENO,
        fd.CENAVYK, fd.CENALEC, fd.CENAKAP
    FROM FAKDET fd
    JOIN FAK f ON f.ID = fd.IDFAK
    LEFT JOIN UZIVATEL u ON u.IDUZI = fd.IDUZI
    ORDER BY fd.IDFAK DESC, fd.ID DESC
''')
det_cols = [d[0] for d in cur.description]
det_rows = cur.fetchall()

ws2.append(det_cols)
for i, row in enumerate(det_rows, start=2):
    ws2.append([fmt(v) for v in row])
    if i % 2 == 0:
        for cell in ws2[i]:
            cell.fill = ZEBRA_FILL

style_header(ws2)
ws2.freeze_panes = 'A2'
autofit(ws2)

# =====================
# List 3 – PORTAL (krátké sloupce)
# =====================

ws3 = wb.create_sheet('PORTAL')

cur.execute('''
    SELECT ID, IDFAK, ODESLANO, CHYBA, STAV, ID_PODANI, IDPODANI, IDCERT,
           DAVKA_ROK, DAVKA_DISK, DAVKA_IDICZ, DAVKA_DATUMOD, DAVKA_DATUMDO,
           DAVKA_CASTKA, BB_DAVKA, BB_FAKTURA
    FROM PORTAL
    ORDER BY ID DESC
''')
portal_cols = [d[0] for d in cur.description]
portal_rows = cur.fetchall()

ws3.append(portal_cols)
for i, row in enumerate(portal_rows, start=2):
    ws3.append([fmt(v) for v in row])
    if i % 2 == 0:
        for cell in ws3[i]:
            cell.fill = ZEBRA_FILL

style_header(ws3)
ws3.freeze_panes = 'A2'
autofit(ws3)

# =====================
# List 4 – PORTAL_DATA (BLOBy)
# =====================

ws4 = wb.create_sheet('PORTAL_DATA')

cur.execute('''
    SELECT ID, ID_PODANI, DAVKA_ROK, DAVKA_DISK, DAVKA_DATUMOD, DAVKA_DATUMDO,
           KDAVKA, FDAVKA, DATA
    FROM PORTAL
    ORDER BY ID DESC
''')
pdata_rows = cur.fetchall()

pdata_cols = ['ID', 'ID_PODANI', 'DAVKA_ROK', 'DAVKA_DISK', 'DAVKA_DATUMOD', 'DAVKA_DATUMDO',
              'KDAVKA', 'FDAVKA', 'DATA']
ws4.append(pdata_cols)

WRAP = Alignment(wrap_text=True, vertical='top')

# Indexy BLOB sloupců: KDAVKA=6, FDAVKA=7, DATA=8
# DATA je XML v win1250, KDAVKA/FDAVKA jsou latin2
BLOB_ENCODINGS = {6: 'cp852', 7: 'cp852', 8: 'cp1250'}

def decode_blob(v, enc):
    if hasattr(v, 'read'):
        raw = v.read()
    else:
        raw = v
    if not raw:
        return ''
    if isinstance(raw, str):
        # fdb dekódoval jako win1250 – vrátíme zpět na bytes, pak dekódujeme správně
        raw = raw.encode('cp1250', errors='replace')
    return raw.decode(enc, errors='replace')

for i, row in enumerate(pdata_rows, start=2):
    out = []
    for col_idx, v in enumerate(row):
        if col_idx in BLOB_ENCODINGS:
            enc = BLOB_ENCODINGS[col_idx]
            out.append(decode_blob(v, enc))
        else:
            out.append(fmt(v))
    ws4.append(out)
    if i % 2 == 0:
        for cell in ws4[i]:
            cell.fill = ZEBRA_FILL
    for cell in ws4[i]:
        cell.alignment = WRAP
    ws4.row_dimensions[i].height = 80

style_header(ws4)
ws4.freeze_panes = 'A2'

# Šířky sloupců PORTAL_DATA
for col, width in zip(['A','B','C','D','E','F','G','H','I'], [6, 26, 8, 6, 12, 12, 80, 20, 60]):
    ws4.column_dimensions[col].width = width

# =====================
# Hyperlinky PORTAL ↔ PORTAL_DATA
# =====================

# Mapa: portal_id → řádek v každém listu
portal_id_to_ws3_row = {}
for i, row in enumerate(portal_rows, start=2):
    portal_id_to_ws3_row[row[0]] = i  # row[0] = ID

portal_id_to_ws4_row = {}
for i, row in enumerate(pdata_rows, start=2):
    portal_id_to_ws4_row[row[0]] = i  # row[0] = ID

# PORTAL → PORTAL_DATA (sloupec A = ID)
for i, row in enumerate(portal_rows, start=2):
    pid = row[0]
    cell = ws3.cell(row=i, column=1)
    if pid in portal_id_to_ws4_row:
        cell.hyperlink = f'#PORTAL_DATA!A{portal_id_to_ws4_row[pid]}'
        cell.font = LINK_FONT

# PORTAL_DATA → PORTAL (sloupec A = ID)
for i, row in enumerate(pdata_rows, start=2):
    pid = row[0]
    cell = ws4.cell(row=i, column=1)
    if pid in portal_id_to_ws3_row:
        cell.hyperlink = f'#PORTAL!A{portal_id_to_ws3_row[pid]}'
        cell.font = LINK_FONT
        cell.alignment = WRAP

# =====================
# Hyperlinky FAK → FAKDET
# =====================

# Mapa: IDFAK → první řádek na listu FAKDET (řádek 1 = záhlaví, data od 2)
idfak_to_row = {}
for i, row in enumerate(det_rows, start=2):
    idfak = row[1]  # IDFAK je druhý sloupec
    if idfak not in idfak_to_row:
        idfak_to_row[idfak] = i

# Přidat sloupec "→FAKDET" jako první sloupec na listu FAK
ws1.insert_cols(1)
ws1.cell(row=1, column=1, value='FAKDET').fill = HEADER_FILL
ws1.cell(row=1, column=1).font = HEADER_FONT
ws1.cell(row=1, column=1).alignment = Alignment(horizontal='center')
ws1.column_dimensions['A'].width = 9

for i, row in enumerate(fak_rows, start=2):
    fak_id = row[0]  # ID je první sloupec z DB
    cell = ws1.cell(row=i, column=1)
    if fak_id in idfak_to_row:
        target_row = idfak_to_row[fak_id]
        cell.value = '>> det'
        cell.hyperlink = f'#FAKDET!A{target_row}'
        cell.font = LINK_FONT
    else:
        cell.value = ''

# =====================
# Uložení
# =====================

conn.close()
wb.save(output_path)
sys.stdout.buffer.write(f'Ulozeno: {output_path}\n'.encode('utf-8'))
sys.stdout.buffer.write(f'FAK: {len(fak_rows)} radku, FAKDET: {len(det_rows)} radku, PORTAL: {len(portal_rows)} radku\n'.encode('utf-8'))
