<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Models\IncidentInjuryClassification;
use App\Models\IncidentNotifiableClassification;
use App\Models\IncidentInjuryType;
use App\Models\IncidentRiskCategory;
use App\Models\SwmsSafetyPlanningQuestion;
use App\Models\SwmsGeneralNote;
use App\Models\SwmsProtectionTool;
use App\Models\Training;

class AiDataService
{
    /**
     * Generate AI data using OpenAI API
     */
    public function generateAiData($systemPrompt, $userPrompt, $context = 'general', $count = 10)
    {
        try {
            $openaiApiKey = config('ai.openai.api_key');
            if (!$openaiApiKey) {
                throw new \Exception('OpenAI API key not configured');
            }

            // Dynamically adjust max_tokens based on count
            $maxTokens = $this->calculateMaxTokens($count, $context);

            $response = Http::withHeaders([
                'Authorization' => 'Bearer ' . $openaiApiKey,
                'Content-Type' => 'application/json',
            ])->post(config('ai.openai.base_url') . '/chat/completions', [
                'model' => config('ai.openai.model'),
                'messages' => [
                    ['role' => 'system', 'content' => $systemPrompt],
                    ['role' => 'user', 'content' => $userPrompt]
                ],
                'temperature' => config('ai.prompts.default.temperature'),
                'max_tokens' => $maxTokens
            ]);

            if (!$response->successful()) {
                Log::error("OpenAI API error for {$context}", [
                    'status' => $response->status(),
                    'response' => $response->body()
                ]);
                throw new \Exception("Failed to generate AI data for {$context}");
            }

            $aiResponse = $response->json();
            return $aiResponse['choices'][0]['message']['content'] ?? '';

        } catch (\Exception $e) {
            Log::error("AI data generation error for {$context}", [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }

    /**
     * Calculate appropriate max_tokens based on count and context
     */
    private function calculateMaxTokens($count, $context)
    {
        // Base token calculation: each item needs roughly 100-200 tokens
        $baseTokensPerItem = 150;
        $estimatedTokens = $count * $baseTokensPerItem;
        
        // Add buffer for system prompt and structure
        $totalEstimated = $estimatedTokens + 1000;
        
        // Use high_count config for high counts
        if ($count > 15) {
            $maxTokens = config('ai.prompts.high_count.max_tokens', 8000);
        } else {
            $maxTokens = config('ai.prompts.default.max_tokens', 4000);
        }
        
        // Ensure we have enough tokens, but don't exceed model limits
        return min($totalEstimated, $maxTokens);
    }

    /**
     * Parse JSON response from AI
     */
    public function parseAiResponse($content, $expectedStructure)
    {
        try {
            // Clean the content to extract only JSON
            $jsonStart = strpos($content, '{');
            $jsonEnd = strrpos($content, '}');
            
            if ($jsonStart === false || $jsonEnd === false) {
                Log::error('No valid JSON structure found in AI response', [
                    'content_preview' => substr($content, 0, 500),
                    'content_length' => strlen($content)
                ]);
                return null;
            }
            
            $jsonContent = substr($content, $jsonStart, $jsonEnd - $jsonStart + 1);
            
            // Try to decode the JSON
            $data = json_decode($jsonContent, true);
            
            if (json_last_error() !== JSON_ERROR_NONE) {
                Log::error('JSON parsing failed', [
                    'json_error' => json_last_error_msg(),
                    'json_content' => $jsonContent,
                    'content_preview' => substr($content, 0, 1000)
                ]);
                return null;
            }

            // Validate the structure
            if (!$this->validateDataStructure($data, $expectedStructure)) {
                Log::error('Data structure validation failed', [
                    'expected_structure' => $expectedStructure,
                    'actual_data_keys' => array_keys($data),
                    'data_preview' => array_slice($data, 0, 2)
                ]);
                return null;
            }

            return $data;

        } catch (\Exception $e) {
            Log::error('Failed to parse AI response', [
                'content' => $content,
                'error' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * Validate data structure against expected format
     */
    private function validateDataStructure($data, $expectedStructure)
    {
        foreach ($expectedStructure as $key => $required) {
            if ($required && (!isset($data[$key]) || !is_array($data[$key]))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Get industry context for prompts
     */
    public function getIndustryContext($industry)
    {
        $contexts = [
            'construction' => 'Construction industry injuries often include falls from heights, manual handling injuries, struck by objects, and machinery-related incidents. Focus on high-risk construction work injuries following Australian Standards.',
            'manufacturing' => 'Manufacturing injuries typically involve machinery accidents, repetitive strain injuries, chemical exposures, and manual handling incidents. Follow Australian manufacturing safety standards.',
            'mining' => 'Mining injuries include underground incidents, machinery accidents, respiratory issues, and environmental hazards. Follow Australian mining safety regulations and standards.',
            'healthcare' => 'Healthcare injuries often involve patient handling, needlestick injuries, workplace violence, and ergonomic issues. Follow Australian healthcare safety standards.',
            'retail' => 'Retail injuries typically include manual handling, slips and trips, customer-related incidents, and ergonomic issues. Follow Australian retail safety guidelines.',
            'transport' => 'Transport injuries include vehicle accidents, loading/unloading injuries, driver fatigue, and road safety incidents. Follow Australian transport safety regulations.',
            'agriculture' => 'Agricultural injuries include machinery accidents, animal-related incidents, chemical exposures, and environmental hazards. Follow Australian agricultural safety standards.',
            'general' => 'General workplace injuries include slips and trips, manual handling, ergonomic issues, and common workplace accidents. Follow Australian WHS legislation and standards.'
        ];

        return $contexts[$industry] ?? $contexts['general'];
    }

    /**
     * Store injury classifications
     */
    public function storeInjuryClassifications($parsedData, $customerId, $workspaceId)
    {
        $storedClassifications = [];
        
        foreach ($parsedData['classifications'] as $classification) {
            $storedClassification = IncidentInjuryClassification::create([
                'title' => $classification['title'],
                'description' => $classification['description'] ?? null,
                'status' => $classification['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedClassifications[] = $storedClassification;
        }

        return $storedClassifications;
    }

    /**
     * Store notifiable classifications
     */
    public function storeNotifiableClassifications($parsedData, $customerId, $workspaceId)
    {
        $storedClassifications = [];
        
        foreach ($parsedData['classifications'] as $classification) {
            $storedClassification = IncidentNotifiableClassification::create([
                'title' => $classification['title'],
                'description' => $classification['description'] ?? null,
                'status' => $classification['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedClassifications[] = $storedClassification;
        }

        return $storedClassifications;
    }

    /**
     * Store injury types
     */
    public function storeInjuryTypes($parsedData, $customerId, $workspaceId)
    {
        $storedInjuryTypes = [];
        
        foreach ($parsedData['injury_types'] as $injuryType) {
            $storedInjuryType = IncidentInjuryType::create([
                'title' => $injuryType['title'],
                'description' => $injuryType['description'],
                'parent_id' => $injuryType['parent_id'],
                'status' => $injuryType['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedInjuryTypes[] = $storedInjuryType;
        }

        return $storedInjuryTypes;
    }

    /**
     * Store incident risk categories
     */
    public function storeIncidentRiskCategories($parsedData, $customerId, $workspaceId)
    {
        $storedRiskCategories = [];
        
        foreach ($parsedData['risk_categories'] as $riskCategory) {
            $storedRiskCategory = IncidentRiskCategory::create([
                'title' => $riskCategory['title'],
                'description' => $riskCategory['description'],
                'status' => 1,
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedRiskCategories[] = $storedRiskCategory;
        }

        return $storedRiskCategories;
    }

    /**
     * Store training data
     */
    public function storeTrainings($parsedData, $customerId, $workspaceId)
    {
        $storedTrainings = [];
        
        foreach ($parsedData['trainings'] as $training) {
            $storedTraining = \App\Models\Training::create([
                'title' => $training['title'],
                'description' => $training['description'] ?? null,
                'status' => $training['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedTrainings[] = $storedTraining;
        }

        return $storedTrainings;
    }

    /**
     * Store incident report questions
     */
    public function storeIncidentReportQuestions($parsedData, $customerId, $workspaceId)
    {
        $storedQuestions = [];
        
        foreach ($parsedData['questions'] as $question) {
            $storedQuestion = \App\Models\IncidentReportQuestion::create([
                'question' => $question['question'],
                'description' => $question['description'] ?? null,
                'status' => $question['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedQuestions[] = $storedQuestion;
        }

        return $storedQuestions;
    }

    /**
     * Store WHS report settings
     */
    public function storeWhsReportSettings($parsedData, $customerId, $workspaceId)
    {
        $storedWhsItems = [];
        
        foreach ($parsedData['whs_items'] as $whsItem) {
            $storedWhsItem = \App\Models\WhsItem::create([
                'title' => $whsItem['title'],
                'status' => $whsItem['status'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
                'created_by' => auth()->id(),
            ]);

            $storedWhsItems[] = $storedWhsItem;
        }

        return $storedWhsItems;
    }

    /**
     * Store SWMS settings
     */
    public function storeSwmsSettings($parsedData, $customerId, $workspaceId)
    {
        $storedHazardRisks = [];
        
        foreach ($parsedData['hazard_risks'] as $hazardRisk) {
            $storedHazardRisk = \App\Models\HazardRisk::create([
                'title' => $hazardRisk['title'],
                'description' => $hazardRisk['description'] ?? null,
                'type' => $hazardRisk['type'],
                'status' => '1',
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedHazardRisks[] = $storedHazardRisk;
        }

        return $storedHazardRisks;
    }

    /**
     * Store SWMS safety planning questions
     */
    public function storeSwmsSafetyPlanningQuestions($parsedData, $customerId, $workspaceId)
    {
        $storedQuestions = [];
        
        foreach ($parsedData['safety_planning_questions'] as $question) {
            $storedQuestion = \App\Models\SwmsSafetyPlanningQuestion::create([
                'question' => $question['question'],
                'description' => $question['description'] ?? null,
                'type' => $question['type'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedQuestions[] = $storedQuestion;
        }

        return $storedQuestions;
    }

    /**
     * Store SWMS general notes
     */
    public function storeSwmsGeneralNotes($parsedData, $customerId, $workspaceId)
    {
        $storedNotes = [];
        
        foreach ($parsedData['general_notes'] as $note) {
            $storedNote = \App\Models\SwmsGeneralNote::create([
                'title' => $note['title'],
                'description' => $note['description'] ?? null,
                'type' => $note['type'],
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedNotes[] = $storedNote;
        }

        return $storedNotes;
    }

    /**
     * Store SWMS protection tools
     */
    public function storeSwmsProtectionTools($parsedData, $customerId, $workspaceId)
    {
        $storedTools = [];
        
        foreach ($parsedData['protection_tools'] as $tool) {
            $storedTool = SwmsProtectionTool::create([
                'title' => $tool['title'],
                'description' => $tool['description'] ?? null,
                'image' => null,
                'customer_id' => $customerId,
                'workspace_id' => $workspaceId,
            ]);

            $storedTools[] = $storedTool;
        }

        return $storedTools;
    }

    /**
     * Get user context (customer ID and workspace ID)
     */
    public function getUserContext($userTable)
    {
        if ($userTable === "customer") {
            return [
                'customer_id' => auth()->id(),
                'workspace_id' => auth()->user()->current_workspace_id
            ];
        } elseif ($userTable === "emp") {
            return [
                'customer_id' => auth()->user()->customer_id,
                'workspace_id' => auth()->user()->workspace_id
            ];
        }
        
        throw new \Exception('You do not have permission to create records.');
    }
}
