"""One-shot: insert 20 baseline time_entries on Dec 31, 2025 attributed to
Rian, marked as already transferred so they contribute to running totals
without polluting /transfer's pending list.

Run with `python3 -u scripts/insert_baseline_entries.py` from /srv/apps/work.
"""
import json
import os
import re
import sys
import urllib.parse
import urllib.request
import uuid
from pathlib import Path


def load_env():
    env_path = Path('/srv/apps/work/.env')
    for line in env_path.read_text().splitlines():
        line = line.strip()
        if not line or line.startswith('#'):
            continue
        m = re.match(r'^([A-Z_]+)\s*=\s*(.*)$', line)
        if m:
            v = m.group(2).strip().strip('"').strip("'")
            os.environ.setdefault(m.group(1), v)


load_env()
BASE = os.environ['NEXT_PUBLIC_SUPABASE_URL'].rstrip('/') + '/rest/v1'
HDRS = {
    'apikey': os.environ['SUPABASE_SECRET_KEY'],
    'Authorization': 'Bearer ' + os.environ['SUPABASE_SECRET_KEY'],
    'Content-Type': 'application/json',
}


def get(path):
    req = urllib.request.Request(BASE + '/' + path, headers=HDRS)
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read().decode())


def post(path, payload, prefer='return=representation'):
    req = urllib.request.Request(
        BASE + '/' + path,
        data=json.dumps(payload).encode(),
        headers={**HDRS, 'Prefer': prefer},
        method='POST',
    )
    with urllib.request.urlopen(req) as r:
        body = r.read().decode()
        return json.loads(body) if body else None


ROWS = [
    ('PlusROI', 'Alluvial Consulting', '5 Hour Support Block', '03:59:24'),
    ('PlusROI', 'Archipeligo', '5 Hours Support Block', '00:00:00'),
    ('PlusROI', 'BAUCO', '5 Hours Support Block', '03:22:12'),
    ('PlusROI', 'CAAT Canada', '5 Hour Support Block', '03:19:48'),
    ('PlusROI', 'City Dogs and City Kitties', '5 Hours Support Block', '02:23:24'),
    ('Bowden Works', 'District of North Saanich', '10 Hours General Support', '03:42:36'),
    ('PlusROI', 'Esko Pacific', '5 Hours General Support', '02:49:48'),
    ('PlusROI', 'Farmer', '5 hour Support Block (Feb/25)', '00:00:00'),
    ('PlusROI', 'FirstOntario Performing Arts Center', '5 Hours Support Block', '00:00:00'),
    ('PlusROI', 'InPlace Technology', '5 Hour Support Block', '01:03:00'),
    ('Bowden Works', 'Marko Juras', '5 Hours General Support', '03:08:24'),
    ('Bowden Works', 'New Perspectives Theatre', '5 Hours Support Block (Ended March 26)', '06:46:12'),
    ('Bowden Works', 'Samir Hire', '5 Hour Support Block', '03:25:48'),
    ('PlusROI', 'Stackd Consulting', '10 Hour Support Block', '00:16:48'),
    ('PlusROI', 'The Academy', '5 Hour Support Block', '00:25:48'),
    ('Bowden Works', 'The Palms', '10 Hour General Support Block', '00:50:24'),
    ('Bowden Works', 'Thereafter', '5 Hours Support Block', '00:41:24'),
    ('Bowden Works', 'The Shore Club', '10 Hour General Support Block', '02:26:24'),
    ('PlusROI', 'Wealth Media Distribution', '5 Hour Support Block', '03:51:36'),
    ('PlusROI', 'Zinc Strategies', '5 Hour Support Block', '01:35:24'),
]
DESCRIPTION = 'Transfer baseline from Toggl, totals as of March 31, 2026'
START_DATE = '2025-12-31'
START_TIME = '00:00:00'


def hms_to_seconds(s):
    h, m, sec = s.split(':')
    return int(h) * 3600 + int(m) * 60 + int(sec)


def seconds_to_hms(total):
    h, rem = divmod(total, 3600)
    m, sec = divmod(rem, 60)
    return f'{h:02d}:{m:02d}:{sec:02d}'


def end_at_from_duration(duration_seconds):
    return f'{START_DATE} {seconds_to_hms(duration_seconds)}'


# 1. Resolve org / Rian / Rian's team / Rian's team_member.
orgs = get("organizations?select=id,name,slug&slug=eq.bowden-works")
org_id = orgs[0]['id']
print(f'org: {orgs[0]["name"]} ({org_id[:8]}...)')

teams = get(f"teams?select=id,name,owner_user_id,base_rate_usd&org_id=eq.{org_id}")
rian_profile = get("profiles?select=id,email,full_name&email=eq.rian@rian.ca")[0]
rian_id = rian_profile['id']
rian_team = next(t for t in teams if t['owner_user_id'] == rian_id)
print(f"Rian's team: {rian_team['name']} ({rian_team['id'][:8]}...) @ ${rian_team['base_rate_usd']}")

rian_members = get(
    f"team_members?select=id,email,display_name,rate_proportion,consolidate_as"
    f"&team_id=eq.{rian_team['id']}&email=eq.rian@rian.ca"
)
if not rian_members:
    sys.exit("ERROR: rian@rian.ca is not a team_member in Rian's team")
rian_member = rian_members[0]
proportion = float(rian_member['rate_proportion'])
converted_user = rian_member.get('consolidate_as') or rian_member['display_name']
base_rate = float(rian_team['base_rate_usd'])
print(
    f"Rian as team_member: {rian_member['id'][:8]}...  "
    f"proportion={proportion}  converted_user={converted_user!r}"
)
# Intentional override for these baseline rows:
#   Rian's normal proportion is 0 (his own time isn't billed at a labor
#   cost). But the user wants the baseline DURATIONS to count toward
#   project billout-hour totals — they only care about hours here, not
#   cost. So:
#     converted_duration_seconds = source duration  (NOT × 0)
#     billout_cost_usd           = 0                (Rian has no cost)
#   Re-resolve on one of these would recompute to zero; they're marked
#   transferred to discourage that.

# 2. Create a batch (clockify_imports row) to group the baseline.
batch = post(
    'clockify_imports',
    {
        'org_id': org_id,
        'imported_by': rian_id,
        'name': 'Manual baseline (2025-12-31)',
        'filename': None,
        'row_count': len(ROWS),
        'notes': 'Baseline totals from Toggl as of March 31, 2026.',
        'source': 'manual',
    },
)
batch_id = batch[0]['id']
print(f'created batch: {batch_id[:8]}...')

# 3. One shared transfer_batch_id since they all "land" together.
transfer_batch_id = str(uuid.uuid4())
now_iso = '2025-12-31T00:00:00+00:00'

entries_payload = []
total_seconds = 0
total_cost = 0.0
for op, client, project, dur_str in ROWS:
    duration_seconds = hms_to_seconds(dur_str)
    # Override: baseline tracks hours, not cost. See note above.
    converted_seconds = duration_seconds
    cost = 0.0
    total_seconds += converted_seconds
    total_cost += cost
    entries_payload.append({
        'org_id': org_id,
        'import_id': batch_id,
        'source_user_name': rian_profile.get('full_name') or 'Rian Bowden',
        'source_user_email': 'rian@rian.ca',
        'operator': op,
        'client': client,
        'project': project,
        'description': DESCRIPTION,
        'billable': True,
        'start_at': f'{START_DATE} {START_TIME}',
        'end_at': end_at_from_duration(duration_seconds),
        'duration_seconds': duration_seconds,
        'team_member_id': rian_member['id'],
        'converted_user': converted_user,
        'converted_duration_seconds': converted_seconds,
        'billout_cost_usd': cost,
        # Pre-transferred — these are baselines, not pending work.
        'transferred_at': now_iso,
        'transferred_by': rian_id,
        'transfer_batch_id': transfer_batch_id,
    })

print()
print('about to insert:')
for e in entries_payload:
    print(
        f"  {e['operator']:14s} / {e['client']:38s} / {e['project']:40s}  "
        f"{seconds_to_hms(e['duration_seconds'])}  ${e['billout_cost_usd']:.2f}"
    )
print()
print(f"total: {len(entries_payload)} rows, {seconds_to_hms(total_seconds)}, ${total_cost:.2f}")

# 4. Bulk insert.
inserted = post('time_entries', entries_payload)
print(f'\ninserted {len(inserted)} rows.')
print(f'transfer_batch_id: {transfer_batch_id}')
