/**
 * Harmony Score Calculation (Cron Job)
 *
 * This function runs periodically (e.g., daily) to recalculate harmony scores
 * for all users based on their recent behavior patterns.
 *
 * Design intent:
 * - Influence adapts automatically based on behavior.
 * - Scores decay over time (old issues fade).
 * - Changes are gradual, not sudden.
 *
 * Trigger: Scheduled via Supabase cron or external scheduler
 */

import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
import { createServiceClient } from '../_shared/supabase-client.ts';
import { calculateHarmonyAdjustment, type HarmonyInputs } from '../_shared/harmony.ts';

serve(async (req) => {
  try {
    // Verify this is a scheduled/cron request
    const authHeader = req.headers.get('Authorization');
    const cronSecret = Deno.env.get('CRON_SECRET');

    if (!authHeader || authHeader !== `Bearer ${cronSecret}`) {
      return new Response(JSON.stringify({ error: 'Unauthorized' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const serviceClient = createServiceClient();

    // 1. Get all users with their current trust state
    const { data: users, error: usersError } = await serviceClient
      .from('trust_state')
      .select('user_id, harmony_score, tier, counters')
      .order('user_id');

    if (usersError) {
      console.error('Error fetching users:', usersError);
      return new Response(JSON.stringify({ error: 'Failed to fetch users' }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
    const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();

    let updatedCount = 0;
    let errorCount = 0;

    // 2. Process each user
    for (const user of users) {
      try {
        // Gather behavior metrics for this user

        // Blocks received
        const { count: blocks7d } = await serviceClient
          .from('blocks')
          .select('*', { count: 'exact', head: true })
          .eq('blocked_id', user.user_id)
          .gte('created_at', sevenDaysAgo);

        const { count: blocks30d } = await serviceClient
          .from('blocks')
          .select('*', { count: 'exact', head: true })
          .eq('blocked_id', user.user_id)
          .gte('created_at', thirtyDaysAgo);

        // Reports against this user
        const { data: reportsAgainst } = await serviceClient
          .from('reports')
          .select('reporter_id, status')
          .or('target_type.eq.post,target_type.eq.comment')
          .in(
            'target_id',
            serviceClient
              .from('posts')
              .select('id')
              .eq('author_id', user.user_id)
              .then((r) => r.data?.map((p) => p.id) || [])
          );

        // Count trusted reports (from high-harmony reporters)
        let trustedReportsCount = 0;
        if (reportsAgainst) {
          for (const report of reportsAgainst) {
            const { data: reporterTrust } = await serviceClient
              .from('trust_state')
              .select('harmony_score')
              .eq('user_id', report.reporter_id)
              .single();

            if (reporterTrust && reporterTrust.harmony_score >= 70) {
              trustedReportsCount++;
            }
          }
        }

        // Posts rejected in last 7 days (from audit log)
        const { data: rejectedPosts } = await serviceClient
          .from('audit_log')
          .select('id')
          .eq('actor_id', user.user_id)
          .eq('event_type', 'post_rejected')
          .gte('created_at', sevenDaysAgo);

        // Posts created in last 7 days
        const { count: postsCreated7d } = await serviceClient
          .from('posts')
          .select('*', { count: 'exact', head: true })
          .eq('author_id', user.user_id)
          .gte('created_at', sevenDaysAgo);

        // Reports filed by user
        const { data: reportsFiled } = await serviceClient
          .from('reports')
          .select('id, status')
          .eq('reporter_id', user.user_id);

        const falseReports = reportsFiled?.filter((r) => r.status === 'dismissed').length || 0;
        const validatedReports = reportsFiled?.filter((r) => r.status === 'resolved').length || 0;

        // Days since signup
        const { data: profile } = await serviceClient
          .from('profiles')
          .select('created_at')
          .eq('id', user.user_id)
          .single();

        const daysSinceSignup = profile
          ? Math.floor((Date.now() - new Date(profile.created_at).getTime()) / (1000 * 60 * 60 * 24))
          : 0;

        // 3. Calculate harmony adjustment
        const inputs: HarmonyInputs = {
          user_id: user.user_id,
          blocks_received_7d: blocks7d || 0,
          blocks_received_30d: blocks30d || 0,
          trusted_reports_against: trustedReportsCount,
          total_reports_against: reportsAgainst?.length || 0,
          posts_rejected_7d: rejectedPosts?.length || 0,
          posts_created_7d: postsCreated7d || 0,
          false_reports_filed: falseReports,
          validated_reports_filed: validatedReports,
          days_since_signup: daysSinceSignup,
          current_harmony_score: user.harmony_score,
          current_tier: user.tier,
        };

        const adjustment = calculateHarmonyAdjustment(inputs);

        // 4. Update trust state if score changed
        if (adjustment.delta !== 0) {
          const { error: updateError } = await serviceClient
            .from('trust_state')
            .update({
              harmony_score: adjustment.new_score,
              tier: adjustment.new_tier,
              updated_at: new Date().toISOString(),
            })
            .eq('user_id', user.user_id);

          if (updateError) {
            console.error(`Error updating trust state for ${user.user_id}:`, updateError);
            errorCount++;
            continue;
          }

          // 5. Log the adjustment
          await serviceClient.rpc('log_audit_event', {
            p_actor_id: null, // system action
            p_event_type: 'harmony_recalculated',
            p_payload: {
              user_id: user.user_id,
              old_score: user.harmony_score,
              new_score: adjustment.new_score,
              delta: adjustment.delta,
              old_tier: user.tier,
              new_tier: adjustment.new_tier,
              reason: adjustment.reason,
            },
          });

          updatedCount++;
        }
      } catch (userError) {
        console.error(`Error processing user ${user.user_id}:`, userError);
        errorCount++;
      }
    }

    return new Response(
      JSON.stringify({
        success: true,
        total_users: users.length,
        updated: updatedCount,
        errors: errorCount,
        message: 'Harmony score recalculation complete',
      }),
      {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
      }
    );
  } catch (error) {
    console.error('Unexpected error:', error);
    return new Response(JSON.stringify({ error: 'Internal server error' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});
