#!/usr/bin/env python3
"""Разбор расхождения ДОХОДЫ CRM(направления) ↔ Финтабло «Выручка b2c» за 2026.
Делит разницу на: (1) доходы CRM, НЕ привязанные к направлению (мерч, внешние и пр.)
и (2) системный/тайминговый остаток. Выгружает конкретные операции (1) в Excel.
"""
import json, os
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill
import margins as m

cats = m.ft_categories()
months = m.months_to_now()

# --- CRM: один проход по приходам 2026, собираем b2c-операции ---
token = m.alfa_login()
pay_items = m._alfa_pay_items(token)
mapped = excluded = 0.0
excl_detail = {}
excl_ops = []          # операции, НЕ попавшие в направления
seen = set()
_df, _dt = m.year_range_alfa()          # ⚠️ только дефисы: с точками AlfaCRM игнорирует фильтр
for br in m.BRANCHES:
    if True:
        items = m.alfa_all(f'/v2api/{br}/pay/index',
                           {'pay_type_id': 1, 'date_from': _df, 'date_to': _dt}, token)
        for x in items:
            pid = x.get('id')
            if pid in seen:
                continue
            seen.add(pid)
            dd = x.get('document_date') or ''
            if len(dd) < 10 or dd[6:10] != '2026':
                continue
            nm = (pay_items.get(x.get('pay_item_id')) or '').strip()
            if 'b2b' in nm.lower():
                continue                       # B2B — отдельно, не b2c
            val = float(x.get('income') or 0)
            if m.income_direction(nm):
                mapped += val
            else:
                excluded += val
                excl_detail[nm] = excl_detail.get(nm, 0) + val
                excl_ops.append({
                    'дата': dd, 'филиал': br, 'статья CRM': nm or '(пусто)',
                    'сумма': val, 'примечание': (x.get('note') or '').strip(),
                })

crm_b2c_total = mapped + excluded
ft_b2c = sum(float(t.get('value') or 0) for mm in months
             for t in m._ft_tx('income', mm)
             if m._norm(cats.get(t.get('categoryId'), '')) == m._norm('Выручка b2c'))
residual = ft_b2c - crm_b2c_total

print(f'Финтабло «Выручка b2c»:            {ft_b2c:14,.0f}')
print(f'CRM b2c всего:                     {crm_b2c_total:14,.0f}')
print(f'  в направлениях (в таблице):      {mapped:14,.0f}')
print(f'  НЕ в направлениях (в разнице):   {excluded:14,.0f}')
for nm, v in sorted(excl_detail.items(), key=lambda x: -x[1]):
    print(f'      {v:12,.0f}  {nm}  ({sum(1 for o in excl_ops if o["статья CRM"]==(nm or "(пусто)"))} опер.)')
print(f'ОСТАТОК Финтабло−CRM (системный/тайминг): {residual:14,.0f}')
print(f'ИТОГО разница (excluded + остаток):        {excluded + residual:14,.0f}')

# --- Excel ---
wb = Workbook()
ws = wb.active
ws.title = 'CRM b2c вне направлений'
head = ['Дата', 'Филиал', 'Статья CRM', 'Сумма', 'Примечание']
ws.append(head)
for c in ws[1]:
    c.font = Font(bold=True, color='FFFFFF')
    c.fill = PatternFill('solid', fgColor='1F2733')
    c.alignment = Alignment(horizontal='center')
for o in sorted(excl_ops, key=lambda x: (x['статья CRM'], x['дата'])):
    ws.append([o['дата'], o['филиал'], o['статья CRM'], o['сумма'], o['примечание']])
ws.append(['', '', 'ИТОГО', excluded, ''])
ws[ws.max_row][2].font = Font(bold=True)
ws[ws.max_row][3].font = Font(bold=True)
widths = [12, 8, 34, 14, 40]
for i, w in enumerate(widths, 1):
    ws.column_dimensions[chr(64 + i)].width = w
for row in ws.iter_rows(min_row=2, min_col=4, max_col=4):
    for c in row:
        c.number_format = '#,##0'
ws.freeze_panes = 'A2'

out = os.path.expanduser('~/Desktop/Расхождение доходов CRM-Финтабло b2c – 2026.xlsx')
wb.save(out)
print('EXCEL →', out, f'({len(excl_ops)} операций)')
