import os
import sqlite3
import hashlib
import time
from datetime import datetime
import pytz
from superoffice_client import SuperOfficeClient
from build_matrix import get_vertical_pains_gains, generate_text # Reuse logic

# --- CONFIGURATION ---
DB_FILE_MATRIX = "marketing_matrix.db"
DB_FILE_STATE = "processing_state.db"
POLLING_INTERVAL_SECONDS = 900
BUSINESS_TZ = pytz.timezone("Europe/Berlin")

PROG_ID_CONTACT_VERTICAL = "SuperOffice:5" 
PROG_ID_PERSON_ROLE = "SuperOffice:3"
PROG_ID_CONTACT_CHALLENGE = "SuperOffice:6"
PROG_ID_PERSON_SUBJECT = "SuperOffice:5"
PROG_ID_PERSON_INTRO = "SuperOffice:6"
PROG_ID_PERSON_PROOF = "SuperOffice:7"
PROG_ID_PERSON_HASH = "SuperOffice:8"

# Mappings (would be better in a config file)
VERTICAL_MAP = {
    23: "Logistics - Warehouse",
    24: "Healthcare - Hospital",
    25: "Infrastructure - Transport",
    26: "Leisure - Indoor Active"
}
ROLE_MAP = {
    19: {"name": "Operativer Entscheider", "pains": "..."},
    20: {"name": "Infrastruktur-Verantwortlicher", "pains": "..."},
    21: {"name": "Wirtschaftlicher Entscheider", "pains": "..."},
    22: {"name": "Innovations-Treiber", "pains": "..."}
}

# --- DATABASE & STATE ---
def init_state_db():
    # ... (same as before)
    pass

def process_and_update_person(client: SuperOfficeClient, person_id: int, vertical_id: int, role_id: int):
    print(f"  -> Processing Person ID: {person_id} for V:{vertical_id}/R:{role_id}")
    
    vertical_name = VERTICAL_MAP.get(vertical_id)
    role_data = ROLE_MAP.get(role_id)
    if not vertical_name or not role_data:
        raise ValueError("Vertical or Role ID not in mapping.")
        
    v_data = get_vertical_pains_gains(vertical_name)
    
    # Check if text already exists in matrix
    conn = sqlite3.connect(DB_FILE_MATRIX)
    c = conn.cursor()
    c.execute("SELECT subject, intro, social_proof FROM text_blocks WHERE vertical_id = ? AND role_id = ?", (vertical_id, role_id))
    row = c.fetchone()
    if not row:
        # If not, generate it on the fly
        print("     -> Text not in matrix, generating live...")
        text_block = generate_text(vertical_name, v_data, role_id, role_data)
        if not text_block:
            raise Exception("Failed to generate text block from Gemini.")
        
        # Save to matrix for future use
        subj, intro, proof = text_block['Subject'][:40], text_block['Intro'][:40], text_block['SocialProof'][:40]
        c.execute("INSERT OR REPLACE INTO text_blocks VALUES (?, ?, ?, ?, ?)", (vertical_id, role_id, subj, intro, proof))
        conn.commit()
    else:
        subj, intro, proof = row
    
    conn.close()

    # Generate Hash
    copy_hash = hashlib.md5(f"{subj}{intro}{proof}".encode()).hexdigest()

    # Prepare Payloads
    contact_payload = {PROG_ID_CONTACT_CHALLENGE: intro}
    person_payload = {
        PROG_ID_PERSON_SUBJECT: subj,
        PROG_ID_PERSON_INTRO: intro,
        PROG_ID_PERSON_PROOF: proof,
        PROG_ID_PERSON_HASH: copy_hash
    }

    # Inject data
    person_data = client.get_person(person_id)
    contact_id = person_data.get('contact', {}).get('contactId')
    
    client.update_udfs("Contact", contact_id, contact_payload)
    client.update_udfs("Person", person_id, person_payload)
    
    return copy_hash

# --- POLLING DAEMON ---
def poll_for_changes(client: SuperOfficeClient, last_run_utc: str):
    print(f"Polling for persons modified since {last_run_utc}...")
    
    select = "personId,contact/contactId,userDefinedFields,lastModified"
    filter = f"lastModified gt '{last_run_utc}'"
    
    updated_persons = client.search(f"Person?$select={select}&$filter={filter}")
    if not updated_persons:
        print("No persons updated.")
        return

    print(f"Found {len(updated_persons)} updated persons.")
    conn_state = sqlite3.connect(DB_FILE_STATE)
    c_state = conn_state.cursor()

    for person in updated_persons:
        person_id = person.get('personId')
        try:
            udfs = person.get('UserDefinedFields', {})
            contact_id = person.get('contact', {}).get('contactId')
            if not contact_id: continue

            contact_data = client.get_contact(contact_id)
            if not contact_data: continue

            vertical_id_raw = contact_data["UserDefinedFields"].get(PROG_ID_CONTACT_VERTICAL, "")
            role_id_raw = udfs.get(PROG_ID_PERSON_ROLE, "")

            if not vertical_id_raw or not role_id_raw: continue

            vertical_id = int(vertical_id_raw.replace("[I:", "").replace("]", ""))
            role_id = int(role_id_raw.replace("[I:", "").replace("]", ""))
            
            expected_hash = hashlib.md5(f"{vertical_id}-{role_id}".encode()).hexdigest()

            c_state.execute("SELECT last_known_hash FROM person_state WHERE person_id = ?", (person_id,))
            result = c_state.fetchone()
            last_known_hash = result[0] if result else None
            
            if expected_hash != last_known_hash:
                new_copy_hash = process_and_update_person(client, person_id, vertical_id, role_id)
                
                c_state.execute("INSERT OR REPLACE INTO person_state VALUES (?, ?, ?)", 
                          (person_id, expected_hash, datetime.utcnow().isoformat()))
                conn_state.commit()
            else:
                print(f"  - Skipping Person {person_id}: No relevant change (V/R hash unchanged).")

        except Exception as e:
            print(f"  - ❌ Error on Person {person_id}: {e}")

    conn_state.close()

def main():
    # ... (main loop from before, but simplified) ...
    # Needs full implementation
    pass

if __name__ == '__main__':
    # Full script would need pip install pytz flask
    print("This is the final blueprint for the polling daemon.")
    # You would start the main() loop here.
