-- OPERANALYTICS-951
-- директовая воронка по смарт-баннерам
-- почти полная копипаста из https://yql.yandex-team.ru/Operations/XsyeY5dg8oxtbMS1o66G4PjKdDTzVioVbqd21hEPlhA=
-- https://datalens.yandex-team.ru/pu5o3crp6dm6l-voronka-direkta-i-vyzhivaemost
USE hahn;

$chevent = "//home/vipplanners/dashboard_smartbanners/daily_v2/chevent";

$orderid_wl = (
SELECT DISTINCT orderid
FROM RANGE($chevent)
WHERE shows_parent > 0
   OR shows_child > 0
);

$orderinfo = (
SELECT
  OrderID
, ClientID
, ExportID AS CampaignID
FROM `//home/yabs/dict/CaesarOrderInfo` AS oi
LEFT SEMI JOIN $orderid_wl AS wl
  ON oi.OrderID = wl.orderid
WHERE EngineID = 7  -- Директ
  AND OrderType = 1  -- Коммерция
  AND NOT ContentTypeWallet
  AND NOT ContentTypeGeo
);

$parse_datetime = DateTime::Parse("%Y-%m-%d %H:%M:%S");
$format = DateTime::Format("%Y-%m-%d");
$parse_date = DateTime::Parse("%Y-%m-%d");

$date_timestamp = ($y) -> {
    return $format(AddTimezone(CAST($y as timestamp), "Europe/Moscow")) ;
};

-- Создание аккаунта в Директе c открутками по товарным фильтрам
$direct_creation_date = (
SELECT 
  clientid
, min(DateTime::MakeDate($parse_datetime(clients.create_date))) AS clientid_date
, min(DateTime::MakeDate(DateTime::StartOfMonth(DateTime::MakeDate($parse_datetime(clients.create_date))))) AS clientid_month
FROM hahn.`home/direct/db/clients` AS clients
LEFT SEMI JOIN $orderinfo AS wl
  ON clients.ClientID = wl.ClientID
GROUP BY cast(clients.ClientID AS int64) AS clientid
);

-- Создание РК с открутками по товарным фильтрам
$first_campaign = 
(
SELECT 
  clientid
, min(DateTime::MakeDate($parse_datetime(create_time))) AS campaign
, min_by(type,create_time) AS camp_type
FROM hahn.`home/direct/db/campaigns` AS c
LEFT SEMI JOIN $orderinfo AS wl
  ON c.cid = wl.CampaignID
GROUP BY
  cast(ClientID AS int64) AS clientid
);

-- Отправка РК c показами по товарным фильтрам на модерацию
-- $moderate_new = (
-- SELECT
--   clientid
-- , min(DateTime::MakeDate(DateTime::MakeDatetime($parse_datetime(timeCreated)))) AS moderate_sent
-- FROM `home/direct-moderate/prod-banners` AS mod
-- LEFT SEMI JOIN $orderinfo AS wl
--   ON mod.cid = wl.CampaignID
-- WHERE statusSync == "Sent" 
--   AND cast(bid AS uint64) > 0
-- GROUP BY cast(clientID AS int64) AS clientid
-- );

-- Прохождение модерации РК с показами по товарным фильтрам
-- $moderate_yes = (
-- SELECT
--   clientid
-- , min(DateTime::MakeDate(DateTime::MakeDatetime($parse_datetime(timeCreated)))) AS moderate_got
-- FROM `home/direct-moderate/prod-banners` AS mod
-- LEFT SEMI JOIN $orderinfo AS wl
--   ON mod.cid = wl.CampaignID
-- WHERE statusSync == "Sent"
--   AND statusModerate == "Yes"
-- GROUP BY cast(clientID AS int64) AS clientid
-- );

-- Создание плательщика с показами по товарным фильтрам
$payer_creation_date = (
SELECT 
  clientid
, cast(min($date_timestamp(dt)) AS date) AS payer
FROM `home/balance/prod/bo/t_person` AS p
LEFT SEMI JOIN $orderinfo AS wl
  ON p.client_id = wl.ClientID
GROUP BY
    cast(client_id AS int64) AS clientid
);

-- Вся информация по счетам и клиентам в баллансе с показами по товарным фильтрам
INSERT INTO @t_invoice WITH TRUNCATE
SELECT
  cast(i.client_id AS int64) AS clientid
, cast($date_timestamp(i.dt) AS date) AS invoice_date  -- дата создания счета
, cast($date_timestamp(i.receipt_dt) AS date) AS receipt_date  -- дата подтверждения оплаты счета
, i.consume_sum ?? 0.0 AS consume_sum  -- сумма оплаты счета
FROM `home/balance/prod/bo/t_invoice` AS i
LEFT SEMI JOIN $orderinfo AS wl
  ON i.client_id = wl.ClientID
LEFT SEMI JOIN (
  SELECT invoice_id
  FROM `home/balance/prod/payments/t_payment`
  WHERE service_id == 7
     OR service_id IS NULL
) AS p
  ON i.id == p.invoice_id
;
COMMIT;

-- Выставление первого счета
$first_invoice = (
SELECT
  clientid
, min(invoice_date) AS invoice
FROM @t_invoice
GROUP BY
  cast(clientid AS int64) AS clientid
);

-- Первая оплата счета
$first_payment = (
SELECT
  clientid
, min(receipt_date) AS payment1
FROM @t_invoice
WHERE consume_sum > 0.0
   OR consume_sum > 0
GROUP BY
  cast(clientid AS int64) AS clientid
);

$second_payment = (
SELECT
  clientid
, min(receipt_date) AS payment2
FROM (
  SELECT
      cast(t0.clientid AS int64) AS clientid, 
      t0.receipt_date AS  receipt_date
  FROM @t_invoice AS t0
  JOIN $first_payment AS t1
    USING (clientid)
  WHERE (t0.consume_sum > 0.0 OR t0.consume_sum > 0)
    AND t0.receipt_date > t1.payment1
)
GROUP BY clientid
);

-- 3 month of money and start show ---------------------------------------------
$client_stat = (
SELECT
  clientid
, eventdate
, SUM(cost_rub_wo_nds) AS cost_rub_wo_nds
FROM RANGE($chevent) AS e
JOIN `//home/yabs/dict/CaesarOrderInfo` AS oi
  ON e.orderid = oi.OrderID
WHERE shows_parent > 0
   OR shows_child > 0
GROUP BY
  oi.ClientID AS clientid
, e.eventdate AS eventdate
);

$list_costs_sum_if = ($xs, $date, $max_age_days) -> {
  $max_interval = DateTime::IntervalFromDays($max_age_days);
  RETURN ListSum(ListMap($xs, ($x) -> (IF(($x.dt - $date) BETWEEN Interval("P0D") AND $max_interval, $x.val, 0))));
};

$money = (
SELECT
  cs.*
, cr.clientid_date AS create_date
, cr.clientid_month AS create_month
FROM (
  SELECT
    clientid
  , CAST(eventdate AS String) AS start_day
  , cost_rub_wo_nds_30d AS money1
  , cost_rub_wo_nds_60d - cost_rub_wo_nds_30d AS money2
  , cost_rub_wo_nds_90d - cost_rub_wo_nds_60d AS money3
  FROM (
    SElECT MIN_BY(TableRow(), eventdate)
    FROM (
      SELECT
        clientid
      , eventdate
      , $list_costs_sum_if(
          AGGREGATE_LIST(AsStruct(cost_rub_wo_nds AS val, eventdate AS dt)) OVER client_90_d, eventdate, 30) ?? 0 AS cost_rub_wo_nds_30d
      , $list_costs_sum_if(
          AGGREGATE_LIST(AsStruct(cost_rub_wo_nds AS val, eventdate AS dt)) OVER client_90_d, eventdate, 60) ?? 0 AS cost_rub_wo_nds_60d
      , $list_costs_sum_if(
          AGGREGATE_LIST(AsStruct(cost_rub_wo_nds AS val, eventdate AS dt)) OVER client_90_d, eventdate, 90) ?? 0 AS cost_rub_wo_nds_90d
      FROM $client_stat
      WINDOW client_90_d AS  (
        PARTITION BY clientid
        ORDER BY eventdate ASC
        ROWS BETWEEN CURRENT ROW AND 90 FOLLOWING
      )
    )
    GROUP BY clientid
  )
  FLATTEN COLUMNS
) AS cs
LEFT JOIN $direct_creation_date AS cr
  ON cs.clientid = cr.clientid
);

INSERT INTO @funnel WITH TRUNCATE
SELECT
  t0.clientid AS clientid
, camp_type
, clientid_date
, clientid_month
, if(campaign > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, campaign) AS campaign
-- , if(moderate_sent > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, moderate_sent) AS moderate_sent
, null AS moderate_sent
-- , if(moderate_got > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, moderate_got) AS moderate_got
, null AS moderate_got
, if(payer > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, payer) AS payer
, if(invoice > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, invoice) AS invoice
, if(payment1 > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, payment1) AS payment1
, if(payment2 > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, payment2) AS payment2
, if(DateTime::MakeDate($parse_date(t8.start_day)) > DateTime::MakeDate(clientid_date + DateTime::IntervalFromDays(89)), null, DateTime::MakeDate($parse_date(t8.start_day))) AS money_start_day
, t8.money1 AS money1
, t8.money2 AS money2
, t8.money3 AS money3
FROM $direct_creation_date AS t0 
LEFT JOIN $first_campaign AS t1
  ON t1.clientid = t0.clientid
-- LEFT JOIN $moderate_new AS t2
--   ON t2.clientid = t0.clientid
-- LEFT JOIN $moderate_yes AS t3
--   ON t3.clientid = t0.clientid
LEFT JOIN $payer_creation_date AS t4
  ON t4.clientid = t0.clientid
LEFT JOIN $first_invoice AS t5
  ON t5.clientid = t0.clientid
LEFT JOIN $first_payment AS t6
  ON t6.clientid = t0.clientid
LEFT JOIN $second_payment AS t7
  ON t7.clientid = t0.clientid
LEFT JOIN $money AS t8
  ON t8.clientid = t0.clientid
;

COMMIT;

$blocked_clients = (
SELECT clientid
FROM `home/direct/db/users`
WHERE statusBlocked = 'Yes'
GROUP BY cast(ClientID AS int64) AS clientid
);

INSERT INTO `//home/vipplanners/dashboard_smartbanners/cube/funnel` WITH TRUNCATE 
SELECT
  f.campaign AS campaign
, f.clientid AS clientid
, f.camp_type AS camp_type
, f.clientid_date AS clientid_date
, f.clientid_month AS clientid_month
, if(f.invoice < f.clientid_date, f.clientid_date, f.invoice) AS invoice
, if(f.moderate_got < f.clientid_date, f.clientid_date, f.moderate_got) AS moderate_got
, if(f.moderate_sent < f.clientid_date, f.clientid_date, f.moderate_sent) AS moderate_sent
, f.money1 AS money1
, f.money2 AS money2
, f.money3 AS money3
, f.money_start_day AS money_start_day
, if(f.payer < f.clientid_date, f.clientid_date, f.payer) AS payer
, if(f.payment1 < f.clientid_date, f.clientid_date, f.payment1) AS payment1
, if(f.payment2 < f.clientid_date, f.clientid_date, f.payment2) AS payment2
-- client info
, crm.curr_client_main_domain AS curr_client_main_domain
, crm.curr_counterparty_reporting_tier.name AS curr_client_tier
, crm.client_login AS client_login
FROM @funnel AS f
LEFT ONLY JOIN $blocked_clients AS bl
  ON f.clientid = bl.clientid
JOIN `//home/comdep-analytics/public/client_tiers/fact/latest_v2` AS crm
  ON f.clientid = crm.client_id
WHERE (
    f.campaign <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR campaign IS NULL
  ) AND (
    f.invoice <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR invoice IS NULL
  ) AND (
    f.moderate_got <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR moderate_got IS NULL
  ) AND (
    f.moderate_sent <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR moderate_sent IS NULL
  ) AND (
    f.payer <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR payer IS NULL
  ) AND (
    f.payment1 <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR payment1 IS NULL
  ) AND (
    f.payment2 <= DateTime::MakeDate(DateTime::ShiftMonths(f.clientid_date, 3)) OR payment2 IS NULL
  )
ORDER BY clientid_month
;