<?php

namespace App\Controllers;

class Analytics extends BaseController
{
    public function index()
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        $dateFrom = trim((string) $this->request->getGet('date_from'));
        $dateTo = trim((string) $this->request->getGet('date_to'));

        if (! $this->isValidDate($dateFrom)) {
            $dateFrom = date('Y-m-01');
        }

        if (! $this->isValidDate($dateTo)) {
            $dateTo = date('Y-m-d');
        }

        if ($dateFrom > $dateTo) {
            [$dateFrom, $dateTo] = [$dateTo, $dateFrom];
        }

        $organizationId = $this->currentOrganizationId();

        $interventionsTotal = $this->interventionBuilder($organizationId, $dateFrom, $dateTo)
            ->select(
                'COUNT(*) AS total,' .
                " SUM(CASE WHEN maintenance_interventions.status IN ('planned','in_progress','on_hold') THEN 1 ELSE 0 END) AS open_total," .
                " SUM(CASE WHEN maintenance_interventions.status = 'completed' THEN 1 ELSE 0 END) AS completed_total," .
                " SUM(CASE WHEN maintenance_interventions.priority = 'critical' THEN 1 ELSE 0 END) AS critical_total," .
                ' COUNT(DISTINCT maintenance_interventions.site_id) AS sites_total,' .
                ' COUNT(DISTINCT maintenance_interventions.turbine_id) AS turbines_total'
            )
            ->get()
            ->getRowArray() ?? [];

        $eventsTotal = $this->eventBuilder($organizationId, $dateFrom, $dateTo)
            ->select('COUNT(*) AS total')
            ->get()
            ->getRowArray() ?? [];

        $blockchainTotal = $this->blockchainBuilder($organizationId, $dateFrom, $dateTo)
            ->select(
                'COUNT(*) AS total,' .
                " SUM(CASE WHEN blockchain_transactions.status = 'confirmed' THEN 1 ELSE 0 END) AS confirmed_total"
            )
            ->get()
            ->getRowArray() ?? [];

        $interventionTrend = $this->interventionBuilder($organizationId, $dateFrom, $dateTo)
            ->select(
                'DATE(COALESCE(maintenance_interventions.reported_at, maintenance_interventions.scheduled_start_at, maintenance_interventions.created_at)) AS period_label,' .
                ' COUNT(*) AS intervention_count'
            )
            ->groupBy('DATE(COALESCE(maintenance_interventions.reported_at, maintenance_interventions.scheduled_start_at, maintenance_interventions.created_at))')
            ->orderBy('period_label', 'ASC')
            ->get()
            ->getResultArray();

        $eventTrend = $this->eventBuilder($organizationId, $dateFrom, $dateTo)
            ->select('DATE(maintenance_events.happened_at) AS period_label, COUNT(*) AS event_count')
            ->groupBy('DATE(maintenance_events.happened_at)')
            ->orderBy('period_label', 'ASC')
            ->get()
            ->getResultArray();

        $siteBreakdown = $this->interventionBuilder($organizationId, $dateFrom, $dateTo)
            ->select('sites.name AS site_name, COUNT(*) AS intervention_count')
            ->groupBy('sites.id, sites.name')
            ->orderBy('intervention_count', 'DESC')
            ->get()
            ->getResultArray();

        $statusBreakdown = $this->interventionBuilder($organizationId, $dateFrom, $dateTo)
            ->select('maintenance_interventions.status, COUNT(*) AS intervention_count')
            ->groupBy('maintenance_interventions.status')
            ->orderBy('intervention_count', 'DESC')
            ->get()
            ->getResultArray();

        $typeBreakdown = $this->interventionBuilder($organizationId, $dateFrom, $dateTo)
            ->select('maintenance_interventions.intervention_type, COUNT(*) AS intervention_count')
            ->groupBy('maintenance_interventions.intervention_type')
            ->orderBy('intervention_count', 'DESC')
            ->get()
            ->getResultArray();

        $eventBreakdown = $this->eventBuilder($organizationId, $dateFrom, $dateTo)
            ->select('maintenance_events.event_type, COUNT(*) AS event_count')
            ->groupBy('maintenance_events.event_type')
            ->orderBy('event_count', 'DESC')
            ->get()
            ->getResultArray();

        return view('analytics/index', [
            'title' => 'Analytics',
            'active' => 'analytics',
            'filters' => [
                'date_from' => $dateFrom,
                'date_to' => $dateTo,
            ],
            'overview' => [
                'interventions' => (int) ($interventionsTotal['total'] ?? 0),
                'open_interventions' => (int) ($interventionsTotal['open_total'] ?? 0),
                'completed_interventions' => (int) ($interventionsTotal['completed_total'] ?? 0),
                'critical_interventions' => (int) ($interventionsTotal['critical_total'] ?? 0),
                'sites' => (int) ($interventionsTotal['sites_total'] ?? 0),
                'turbines' => (int) ($interventionsTotal['turbines_total'] ?? 0),
                'events' => (int) ($eventsTotal['total'] ?? 0),
                'blockchain_transactions' => (int) ($blockchainTotal['total'] ?? 0),
                'confirmed_transactions' => (int) ($blockchainTotal['confirmed_total'] ?? 0),
            ],
            'interventionTrend' => $interventionTrend,
            'eventTrend' => $eventTrend,
            'siteBreakdown' => $siteBreakdown,
            'statusBreakdown' => $statusBreakdown,
            'typeBreakdown' => $typeBreakdown,
            'eventBreakdown' => $eventBreakdown,
        ]);
    }

    private function isValidDate(string $date): bool
    {
        if ($date === '') {
            return false;
        }

        $parsed = date_create($date);

        return $parsed !== false && $parsed->format('Y-m-d') === $date;
    }

    private function interventionBuilder(?int $organizationId, string $dateFrom, string $dateTo)
    {
        $builder = db_connect()->table('maintenance_interventions')
            ->join('sites', 'sites.id = maintenance_interventions.site_id')
            ->join('turbines', 'turbines.id = maintenance_interventions.turbine_id', 'left')
            ->where('DATE(COALESCE(maintenance_interventions.reported_at, maintenance_interventions.scheduled_start_at, maintenance_interventions.created_at)) >=', $dateFrom)
            ->where('DATE(COALESCE(maintenance_interventions.reported_at, maintenance_interventions.scheduled_start_at, maintenance_interventions.created_at)) <=', $dateTo);

        if (! $this->isPlatformAdmin() && $organizationId !== null) {
            $builder->where('maintenance_interventions.organization_id', $organizationId);
        }

        return $builder;
    }

    private function eventBuilder(?int $organizationId, string $dateFrom, string $dateTo)
    {
        $builder = db_connect()->table('maintenance_events')
            ->join(
                'maintenance_interventions',
                'maintenance_interventions.id = maintenance_events.maintenance_intervention_id'
            )
            ->where('DATE(maintenance_events.happened_at) >=', $dateFrom)
            ->where('DATE(maintenance_events.happened_at) <=', $dateTo);

        if (! $this->isPlatformAdmin() && $organizationId !== null) {
            $builder->where('maintenance_interventions.organization_id', $organizationId);
        }

        return $builder;
    }

    private function blockchainBuilder(?int $organizationId, string $dateFrom, string $dateTo)
    {
        $builder = db_connect()->table('blockchain_transactions')
            ->join(
                'maintenance_interventions',
                'maintenance_interventions.id = blockchain_transactions.maintenance_intervention_id'
            )
            ->where('DATE(blockchain_transactions.created_at) >=', $dateFrom)
            ->where('DATE(blockchain_transactions.created_at) <=', $dateTo);

        if (! $this->isPlatformAdmin() && $organizationId !== null) {
            $builder->where('maintenance_interventions.organization_id', $organizationId);
        }

        return $builder;
    }
}
