import { Injectable, inject, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, map, catchError } from 'rxjs';
import { AiProvider, AiReportRequest } from '../models/feedback.model';

interface AiConfig {
  provider: AiProvider;
  deepseekKey: string;
  chatgptKey: string;
}

@Injectable({ providedIn: 'root' })
export class AiReportService {
  private http = inject(HttpClient);

  private readonly SETTINGS_KEY = 'moon-feedback-ai-config';
  private readonly DEEPSEEK_URL = 'https://api.deepseek.com/v1/chat/completions';
  private readonly OPENAI_URL = 'https://api.openai.com/v1/chat/completions';

  generating = signal(false);

  getConfig(): AiConfig {
    try {
      const stored = localStorage.getItem(this.SETTINGS_KEY);
      if (stored) return JSON.parse(stored);
    } catch {}
    return {
      provider: 'deepseek',
      deepseekKey: 'sk-8c794ebada1f44df977307ff3da88b38',
      chatgptKey: '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',
    };
  }

  saveConfig(config: AiConfig): void {
    localStorage.setItem(this.SETTINGS_KEY, JSON.stringify(config));
  }

  generateReport(request: AiReportRequest): Observable<{ report: string; provider: AiProvider }> {
    this.generating.set(true);
    const config = this.getConfig();
    const prompt = this.buildPrompt(request);
    const hasImage = !!request.screenshot_base64;

    const primary = config.provider;
    const fallback: AiProvider = primary === 'deepseek' ? 'chatgpt' : 'deepseek';

    return this.callProvider(primary, prompt, request.screenshot_base64, config).pipe(
      catchError(() => this.callProvider(fallback, prompt, request.screenshot_base64, config)),
      map((result) => {
        this.generating.set(false);
        return result;
      }),
      catchError((err) => {
        this.generating.set(false);
        throw err;
      }),
    );
  }

  private callProvider(
    provider: AiProvider,
    prompt: string,
    screenshotBase64: string | undefined,
    config: AiConfig,
  ): Observable<{ report: string; provider: AiProvider }> {
    const url = provider === 'deepseek' ? this.DEEPSEEK_URL : this.OPENAI_URL;
    const key = provider === 'deepseek' ? config.deepseekKey : config.chatgptKey;

    // DeepSeek doesn't support vision — always text only
    // ChatGPT uses gpt-4o when image is present for better vision analysis
    const hasImage = !!screenshotBase64;
    let model: string;
    if (provider === 'deepseek') {
      model = 'deepseek-chat';
    } else {
      model = 'gpt-4o-mini';
    }

    const messages = this.buildMessages(prompt, provider === 'chatgpt' ? screenshotBase64 : undefined);

    if (!key) {
      return new Observable((subscriber) =>
        subscriber.error(new Error(`No API key for ${provider}`)),
      );
    }

    return this.http
      .post<any>(
        url,
        {
          model,
          messages,
          max_tokens: 2000,
          temperature: 0.3,
        },
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${key}`,
          },
        },
      )
      .pipe(
        map((response) => ({
          report: response.choices?.[0]?.message?.content || 'No report generated',
          provider,
        })),
      );
  }

  private buildMessages(prompt: string, screenshotBase64?: string): any[] {
    if (screenshotBase64) {
      return [
        {
          role: 'user',
          content: [
            { type: 'text', text: prompt + '\n\nPlease analyze the attached screenshot carefully to understand the visual context and identify UI elements, layout issues, or any visible problems.' },
            { type: 'image_url', image_url: { url: screenshotBase64 } },
          ],
        },
      ];
    }
    return [{ role: 'user', content: prompt }];
  }

  private buildPrompt(request: AiReportRequest): string {
    const base = `You are a software analyst helping generate structured reports for a developer team.
The application is an Arabic-first ERP system (Moon ERP) built with Angular 21 + PrimeNG (Frontend) and Laravel PHP (Backend API).
Generate the report in Arabic with technical terms in English where appropriate.
Be concise and actionable.

IMPORTANT: Every report MUST include a "التصنيف (Classification)" section at the very top with:
- 🔴 Backend (API/Server) — if the issue is related to API responses, data, server errors, business logic, database
- 🔵 Frontend (UI) — if the issue is related to layout, styling, components, forms, navigation, display
- 🟡 Backend + Frontend — if it requires changes on both sides
Explain briefly WHY you classified it this way.

`;

    switch (request.type) {
      case 'bug':
        return base + this.buildBugPrompt(request);
      case 'change_request':
        return base + this.buildChangeRequestPrompt(request);
      case 'improvement':
        return base + this.buildImprovementPrompt(request);
      case 'feature_request':
        return base + this.buildFeatureRequestPrompt(request);
    }
  }

  private buildBugPrompt(r: AiReportRequest): string {
    return `Generate a BUG REPORT with these sections:
## عنوان مختصر (Short Title)
## الشدة (Severity): Critical/High/Medium/Low
## المكان (Location): ${r.page_url} - ${r.screen_name}
## خطوات إعادة الإنتاج (Steps to Reproduce):
${r.steps_to_reproduce || 'Not provided'}
## النتيجة المتوقعة (Expected):
${r.expected_result || 'Not provided'}
## النتيجة الفعلية (Actual):
${r.actual_result || 'Not provided'}
## وصف إضافي:
${r.description}
${r.target_elements?.length ? `## العنصر المستهدف: ${r.target_elements.map((e) => `${e.tag}#${e.id}.${e.classes.join('.')} "${e.text}"`).join(', ')}` : ''}

Generate:
1. التصنيف (Classification): 🔴 Backend / 🔵 Frontend / 🟡 Both — with brief reasoning
2. Clear title
3. Severity assessment
4. Detailed reproduction steps
5. Root cause hypothesis
6. Suggested fix approach (specify if backend fix, frontend fix, or both)`;
  }

  private buildChangeRequestPrompt(r: AiReportRequest): string {
    return `Generate a CHANGE REQUEST SPECIFICATION:
## المكان: ${r.module} > ${r.screen_name}
## نوع التعديل: ${r.change_type}
## الوضع الحالي (As-Is):
${r.as_is || 'Not provided'}
## المطلوب (To-Be):
${r.to_be || 'Not provided'}
## السبب (Why):
${r.why || 'Not provided'}
## وصف إضافي:
${r.description}
${r.target_elements?.length ? `## العناصر المستهدفة: ${r.target_elements.map((e) => `${e.tag}#${e.id} "${e.text}" at ${e.css_path}`).join('\n')}` : ''}

Generate:
1. التصنيف (Classification): 🔴 Backend / 🔵 Frontend / 🟡 Both — with brief reasoning
2. عنوان مختصر (Short Title)
3. المواصفة التفصيلية (Detailed Specification)
4. شروط القبول (Acceptance Criteria) - numbered list
5. تحليل التأثير (Impact Analysis)
6. ملاحظات للمبرمج (Developer Notes) — specify backend vs frontend tasks`;
  }

  private buildImprovementPrompt(r: AiReportRequest): string {
    return `Generate an IMPROVEMENT PROPOSAL:
## المكان: ${r.module} > ${r.screen_name}
## الأهمية: ${r.priority || 'medium'}
## الوصف:
${r.description}
${r.target_elements?.length ? `## العناصر: ${r.target_elements.map((e) => `${e.tag}#${e.id} "${e.text}"`).join(', ')}` : ''}

Generate:
1. التصنيف (Classification): 🔴 Backend / 🔵 Frontend / 🟡 Both — with brief reasoning
2. عنوان مختصر
3. الوضع الحالي (Current State)
4. التحسين المقترح (Proposed Enhancement)
5. القيمة المضافة (Business Value)
6. شروط القبول (Acceptance Criteria)`;
  }

  private buildFeatureRequestPrompt(r: AiReportRequest): string {
    return `Generate a FEATURE REQUEST SPECIFICATION:
## المكان: ${r.module} > ${r.screen_name}
## الأهمية: ${r.priority || 'medium'}
## نوع القالب: ${r.template_type || 'N/A'}
## الوصف:
${r.description}

Generate:
1. التصنيف (Classification): 🔴 Backend / 🔵 Frontend / 🟡 Both — with brief reasoning
2. عنوان مختصر
3. مواصفة الميزة (Feature Specification)
4. قصص المستخدم (User Stories) - as "بصفتي [role]، أريد [action]، حتى [benefit]"
5. شروط القبول (Acceptance Criteria) - numbered list
6. اعتبارات التصميم (Design Considerations) — specify backend vs frontend tasks`;
  }
}
