from __future__ import annotations
from decimal import Decimal, InvalidOperation
from pathlib import Path
from sqlite3 import Connection
from .common import ImportResult, clean, create_import_session, require_text, source_hash, stable_id, utc_now
from .dry_run import read_csv_rows
from .row_hash import compute_row_hash
REQUIRED_COLUMNS={"name","asset_class","reason","status"}; VALID_STATUS={'active','paused','rejected','closed'}; VALID_CLASS={'Stock','ETF','Crypto','Cash','Bond','Commodity','Other'}
def dec(v):
    t=clean(v)
    if not t: return None
    return Decimal(t)
def import_watchlist_csv(conn:Connection,path:str|Path,*,commit:bool,source_filename:str|None=None)->ImportResult:
    rows,errors=read_csv_rows(path,REQUIRED_COLUMNS); source_filename=source_filename or Path(path).name
    new=existing=0; vals=[]; seen=set()
    for line,row in enumerate(rows,start=2):
        try:
            rh=compute_row_hash(row)
            if rh in seen: raise ValueError(f"line {line}: duplicate row hash in source file")
            seen.add(rh); name=require_text(row,'name',line); ac=require_text(row,'asset_class',line); reason=require_text(row,'reason',line); status=require_text(row,'status',line).lower()
            if ac not in VALID_CLASS: raise ValueError(f"line {line}: invalid asset_class")
            if status not in VALID_STATUS: raise ValueError(f"line {line}: invalid status")
            wid=stable_id('watch',name,ac); exists=conn.execute('SELECT 1 FROM watchlist WHERE watchlist_id=?',(wid,)).fetchone() is not None
            existing += 1 if exists else 0; new += 0 if exists else 1
            vals.append((wid,name,ac,reason,status,dec(row.get('target_entry_price')),clean(row.get('target_entry_currency')) or None,clean(row.get('investment_case')),clean(row.get('bear_case'))))
        except (ValueError,InvalidOperation) as exc: errors.append(str(exc))
    status_txt='failed' if errors else ('committed' if commit else 'dry_run_ok')
    if commit and not errors:
        now=utc_now()
        for v in vals:
            conn.execute('INSERT OR IGNORE INTO watchlist(watchlist_id,name,asset_class,reason,status,target_entry_price,target_entry_currency,investment_case,bear_case,created_at) VALUES(?,?,?,?,?,?,?,?,?,?)',(v[0],v[1],v[2],v[3],v[4],str(v[5]) if v[5] is not None else None,v[6],v[7],v[8],now))
    sid=create_import_session(conn,import_type='watchlist',source_filename=source_filename,file_hash=source_hash(path),status=status_txt,rows_total=len(rows),rows_imported=new if commit and not errors else 0,rows_failed=len(errors),errors=errors,notes='dry run' if not commit else None)
    return ImportResult(sid,'watchlist',status_txt,len(rows),new if not errors else 0,existing,len(errors),errors)
