from flask import Flask, request, jsonify
import os
import sqlite3
import hashlib
from superoffice_client import SuperOfficeClient # Our new shiny client class

app = Flask(__name__)

# --- CONFIGURATION ---
DB_FILE = "marketing_matrix.db"

# UDF ProgIds (from our plan)
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"

# --- CORE LOGIC ---
def get_text_from_matrix(vertical_id, role_id):
    """Fetches the pre-generated text block from the local SQLite DB."""
    conn = sqlite3.connect(DB_FILE)
    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()
    conn.close()
    return row if row else (None, None, None)

def process_single_person(client: SuperOfficeClient, person_id: int):
    """Central logic to update marketing copy for a single person."""
    print(f"Processing Person ID: {person_id}")

    person_data = client.get_person(person_id)
    if not person_data:
        raise ValueError(f"Person {person_id} not found")

    contact_id = person_data.get('contact', {}).get('contactId')
    if not contact_id:
        raise ValueError("Person is not linked to a Contact")

    contact_data = client.get_contact(contact_id)
    if not contact_data:
        raise ValueError(f"Contact {contact_id} not found")

    # Extract and clean Vertical and Role IDs
    vertical_id_raw = contact_data["UserDefinedFields"].get(PROG_ID_CONTACT_VERTICAL, "")
    role_id_raw = person_data["UserDefinedFields"].get(PROG_ID_PERSON_ROLE, "")

    if not vertical_id_raw or not role_id_raw:
        raise ValueError("Vertical or Role ID is not set.")

    vertical_id = int(vertical_id_raw.replace("[I:", "").replace("]", ""))
    role_id = int(role_id_raw.replace("[I:", "").replace("]", ""))

    # Get text from matrix
    subject, intro, proof = get_text_from_matrix(vertical_id, role_id)
    if not subject:
        raise ValueError(f"No text found in matrix for V:{vertical_id}, R:{role_id}")
    
    # Generate Hash
    text_concat = f"{subject}{intro}{proof}"
    copy_hash = hashlib.md5(text_concat.encode()).hexdigest()

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

    # Inject data
    client.update_udfs("Contact", contact_id, contact_payload)
    client.update_udfs("Person", person_id, person_payload)
    
    return f"Updated Person {person_id} with texts for V:{vertical_id}/R:{role_id}"

# --- WEBHOOK ENDPOINTS ---
@app.route('/regenerate_for_person', methods=['POST'])
def webhook_person():
    data = request.get_json()
    if not data or "person_id" not in data:
        return jsonify({"error": "Missing person_id"}), 400
    
    try:
        client = SuperOfficeClient()
        message = process_single_person(client, data['person_id'])
        return jsonify({"status": "success", "message": message}), 200
    except Exception as e:
        print(f"❌ Error processing person: {e}")
        return jsonify({"error": str(e)}), 500

@app.route('/regenerate_for_contact', methods=['POST'])
def webhook_contact():
    data = request.get_json()
    if not data or "contact_id" not in data:
        return jsonify({"error": "Missing contact_id"}), 400
    
    contact_id = data['contact_id']
    print(f"Received request to regenerate for all persons in Contact ID: {contact_id}")

    try:
        client = SuperOfficeClient()
        contact = client.get_contact(contact_id)
        if not contact or not contact.get('persons'):
            return jsonify({"status": "success", "message": "No persons found for this contact."}), 200

        updated_count = 0
        for person_summary in contact['persons']:
            try:
                process_single_person(client, person_summary['personId'])
                updated_count += 1
            except Exception as e:
                print(f"  - Skipping Person {person_summary.get('personId')}: {e}")
        
        return jsonify({"status": "success", "message": f"Processed {updated_count} persons for Contact {contact_id}"}), 200

    except Exception as e:
        print(f"❌ Error processing contact: {e}")
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    # For local dev. Use a proper WSGI server (Gunicorn) for production.
    # Needs pip install Flask
    app.run(host='0.0.0.0', port=5001, debug=True)
