#!/usr/bin/env python3
"""Audit/repair pending follow-ups that contradict the current opportunity stage.

Dry-run by default. Use --apply to update rows. The repair is idempotent and
never sends email or Chatwoot messages.
"""
from __future__ import annotations

import argparse
import os
from pathlib import Path

from dotenv import load_dotenv
from sqlalchemy import create_engine, text


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--apply", action="store_true")
    args = parser.parse_args()
    load_dotenv(dotenv_path=Path(".env"), override=False)
    db_url = os.environ.get("DATABASE_URL")
    if not db_url:
        raise SystemExit("DATABASE_URL em falta")
    engine = create_engine(db_url)

    select_sql = text("""
        SELECT t.id::text AS task_id,
               t.opportunity_id::text,
               o.customer_name,
               o.stage,
               t.action_code,
               t.action,
               t.route,
               t.status,
               EXISTS (
                   SELECT 1 FROM tasks tx
                   WHERE tx.opportunity_id = o.id
                     AND tx.status = 'pending'
                     AND tx.action_code IN ('SEND_INVOICE','CONFIRM_PAYMENT','PREPARE_ORDER','CREATE_SHIPMENT')
               ) AS has_superseding_task
        FROM tasks t
        JOIN opportunities o ON o.id = t.opportunity_id
        WHERE o.status = 'open'
          AND t.status = 'pending'
          AND t.action_code IN ('FOLLOW_UP_QUOTE','FOLLOW_UP_PROFORMA')
          AND (
              upper(o.stage) IN (
                  'INVOICE_REQUESTED','INVOICE_SENT','WAITING_PAYMENT','PAYMENT_CONFIRMED',
                  'ODOO_ORDER_CREATED','IN_PRODUCTION','ORDER_PREPARATION','READY_TO_SHIP',
                  'INVOICED','SHIPMENT_CREATED','SHIPPED','TRACKING_SENT','DELIVERED','WON'
              )
              OR EXISTS (
                  SELECT 1 FROM tasks tx
                  WHERE tx.opportunity_id = o.id
                    AND tx.status = 'pending'
                    AND tx.action_code IN ('SEND_INVOICE','CONFIRM_PAYMENT','PREPARE_ORDER','CREATE_SHIPMENT')
              )
          )
        ORDER BY o.updated_at DESC
    """)
    with engine.begin() as conn:
        rows = [dict(r) for r in conn.execute(select_sql).mappings().all()]
    print(f"Candidatos: {len(rows)}")
    for row in rows:
        decision = "close" if row["has_superseding_task"] or row["stage"] != "WAITING_PAYMENT" else "convert_to_payment"
        print(f"{decision:20} {row['task_id']} | {row['customer_name']} | {row['stage']} | {row['action_code']}")
    if not args.apply:
        print("Dry-run: use --apply para corrigir.")
        return 0

    from app.followup_service import align_pending_followups_for_opportunity
    opportunity_ids = sorted({r["opportunity_id"] for r in rows})
    updated = closed = 0
    for opportunity_id in opportunity_ids:
        result = align_pending_followups_for_opportunity(opportunity_id=opportunity_id, created_by="repair_stale_followups")
        updated += int(result.get("updated") or 0)
        closed += int(result.get("closed") or 0)
        print(opportunity_id, result)
    print(f"Aplicado: convertidas={updated}; encerradas={closed}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
