#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import io

# Force UTF-8 output for Scheduled Tasks
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

"""
FIO EXPORT SCRIPT — FULLY COMMENTED VERSION
-------------------------------------------

This script connects to your MySQL "fio" database,
reads all transactions, and exports them into a highly formatted
Excel workbook.

Excel file includes:

 • First sheet: "ALL" → contains ALL transactions
 • Additional sheets: one for each account from accounts.json
 • First 5 CZK sheets appear first in custom order
 • All formatting exactly preserved (colors, borders, widths, formulas)

Everything is generated automatically.
"""

import mysql.connector
from mysql.connector import Error
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from datetime import datetime
import os
import glob
import json

# ======================================================
# CONFIGURATION
# ======================================================

# MySQL server parameters
DB_HOST = "192.168.1.76"
DB_PORT = 3306
DB_USER = "root"
DB_PASS = "Vlado9674+"
DB_NAME = "fio"

# Where to save Excel files
OUTPUT_DIR = r"u:\Dropbox\!!!Days\Downloads Z230"

# JSON file with list of accounts (name + account_number)
ACCOUNTS_JSON = r"accounts.json"

# Columns that MUST be written as TEXT in Excel using ="value"
# to avoid Excel stripping zeros or changing formatting
TEXT_COLUMNS = ["cislo_uctu", "protiucet", "kod_banky", "ks", "vs", "ss"]


# ======================================================
# REMOVE OLD EXPORT FILES
# ======================================================

def cleanup_old_exports():
    """
    Deletes older versions of exported XLSX files that match
    specific filename patterns. This keeps your folder clean,
    ensuring you only have the most recent export.
    """
    patterns = [
        os.path.join(OUTPUT_DIR, "*FIO*transaction*.xlsx"),
        os.path.join(OUTPUT_DIR, "*FIO*transactions*.xlsx"),
        os.path.join(OUTPUT_DIR, "*FIO_transactions*.xlsx"),
    ]

    # Check each pattern
    for pattern in patterns:
        for file in glob.glob(pattern):
            try:
                os.remove(file)
                print(f"🗑 Deleted old export: {file}")
            except:
                # If file cannot be deleted (locked or permission denied),
                # simply skip it.
                pass


# ======================================================
# CORE EXCEL FORMATTING FUNCTION
# ======================================================

def format_sheet(ws, rows, headers):
    """
    Applies ALL formatting rules to a worksheet:
    - Writes headers
    - Writes all rows
    - Converts selected columns to Excel text formulas
    - Colors rows based on "objem" (red=negative, green=positive)
    - Sets fixed column widths
    - Adds borders to every cell
    - Center-aligns first 10 columns
    - Freezes header row and enables filtering
    """

    # -------------------------------
    # 1) Format HEADER row
    # -------------------------------
    for col_idx in range(1, len(headers) + 1):
        cell = ws.cell(row=1, column=col_idx)
        cell.font = Font(bold=True)                         # bold text
        cell.fill = PatternFill(start_color="FFFF00", fill_type="solid")  # yellow background

    # -------------------------------
    # 2) Write DATA rows
    # -------------------------------
    for row in rows:
        excel_row = []
        for h in headers:
            val = row[h]

            # For text-sensitive columns, write ="value"
            # This prevents Excel from stripping zeros or treating them as numbers.
            if h in TEXT_COLUMNS and val is not None:
                excel_row.append(f'="{val}"')
            else:
                excel_row.append(val)

        ws.append(excel_row)

    # -------------------------------
    # 3) Background coloring by "objem"
    # -------------------------------
    # Light red (ARGB) = negative
    fill_red = PatternFill(start_color="FFFFDDDD", end_color="FFFFDDDD", fill_type="solid")
    # Light green (ARGB) = positive or zero
    fill_green = PatternFill(start_color="FFEEFFEE", end_color="FFEEFFEE", fill_type="solid")

    # Find column index where "objem" is located
    objem_col_index = headers.index("objem") + 1

    # Apply row coloring
    for row_idx in range(2, len(rows) + 2):  # Start at row 2 (row 1 = header)
        cell_objem = ws.cell(row=row_idx, column=objem_col_index)

        # Convert objem to float
        try:
            value = float(cell_objem.value)
        except:
            value = 0

        # Choose correct color
        fill = fill_red if value < 0 else fill_green

        # Apply fill to entire row
        for col_idx in range(1, len(headers) + 1):
            ws.cell(row=row_idx, column=col_idx).fill = fill

    # -------------------------------
    # 4) Fixed column widths
    # -------------------------------
    fixed_widths = [
        6, 11, 11, 5, 14, 14, 8, 6, 13, 13,
        50, 53, 12, 12, 5, 49, 29, 5, 29, 16,
        15, 12, 49, 20
    ]

    # Apply width using A, B, C... column names
    for i, width in enumerate(fixed_widths, start=1):
        col_letter = chr(64 + i)  # convert 1 → 'A', 2 → 'B', ...
        ws.column_dimensions[col_letter].width = width

    # -------------------------------
    # 5) Add borders + alignment
    # -------------------------------
    thin = Side(border_style="thin", color="000000")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)
    align_center = Alignment(horizontal="center")

    total_rows = len(rows) + 1
    total_cols = len(headers)

    for row_idx in range(1, total_rows + 1):
        for col_idx in range(1, total_cols + 1):
            cell = ws.cell(row=row_idx, column=col_idx)
            cell.border = border  # add border

            # Center-align ONLY first 10 columns
            if col_idx <= 10:
                cell.alignment = align_center

    # Freeze header row so it stays visible while scrolling
    ws.freeze_panes = "A2"

    # Enable auto filter on top row
    ws.auto_filter.ref = ws.dimensions


# ======================================================
# MAIN EXPORT PROCESS
# ======================================================

def export_fio():
    print("Connecting to MySQL...")

    # Connect to MySQL database
    try:
        conn = mysql.connector.connect(
            host=DB_HOST,
            port=DB_PORT,
            user=DB_USER,
            password=DB_PASS,
            database=DB_NAME
        )
    except Error as e:
        print("❌ Failed to connect:", e)
        return

    cur = conn.cursor(dictionary=True)

    # -------------------------------
    # Load accounts.json
    # -------------------------------
    with open(ACCOUNTS_JSON, "r", encoding="utf-8") as f:
        accounts = json.load(f)

    # -------------------------------
    # Define priority first sheets
    # -------------------------------
    preferred_order = [
        "CZK rodina",
        "CZK ordinace",
        "CZK na jídlo",
        "CZK TrialHelp",
        "CZK maminka svojě věci"
    ]

    accounts_sorted = []

    # Step 1: add priority accounts first
    for pref in preferred_order:
        for acc in accounts:
            if acc["name"] == pref:
                accounts_sorted.append(acc)

    # Step 2: add remaining accounts afterward
    for acc in accounts:
        if acc not in accounts_sorted:
            accounts_sorted.append(acc)

    # -------------------------------
    # Create a new Excel workbook
    # -------------------------------
    wb = Workbook()
    wb.remove(wb.active)  # remove default empty sheet

    # -------------------------------
    # FIRST SHEET: ALL TRANSACTIONS
    # -------------------------------
    cur.execute("SELECT * FROM transactions ORDER BY datum DESC")
    all_rows = cur.fetchall()

    if all_rows:
        headers = list(all_rows[0].keys())
        ws_all = wb.create_sheet(title="ALL")
        ws_all.append(headers)
        format_sheet(ws_all, all_rows, headers)

    # -------------------------------
    # INDIVIDUAL SHEETS PER ACCOUNT
    # -------------------------------
    for acc in accounts_sorted:
        acc_num = acc["account_number"]
        sheet_name = acc["name"][:31]  # Excel sheet name limit

        print(f"➡ Creating sheet: {sheet_name}")

        query = f"""
            SELECT *
            FROM transactions
            WHERE cislo_uctu = '{acc_num}'
            ORDER BY datum DESC
        """

        cur.execute(query)
        rows = cur.fetchall()

        if not rows:
            print(f"⚠ No data for {sheet_name}")
            continue

        headers = list(rows[0].keys())
        ws = wb.create_sheet(title=sheet_name)
        ws.append(headers)

        format_sheet(ws, rows, headers)

    conn.close()

    # -------------------------------
    # Save Excel file
    # -------------------------------

    cleanup_old_exports()

    # File name includes timestamp
    timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
    filename = f"{timestamp} FIO transactions.xlsx"
    output_file = os.path.join(OUTPUT_DIR, filename)

    wb.save(output_file)

    print(f"✅ Export complete:\n{output_file}")


# ======================================================
# MAIN ENTRY POINT
# ======================================================

if __name__ == "__main__":
    export_fio()
