package com.saas.admin.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * Vapi.ai Call Entity
 * 
 * Stores call history from Vapi.ai voice assistants
 * - Stored in admin database (saas_db) with tenantId for multi-tenant isolation
 * - Populated via webhooks (end-of-call-report) from Vapi.ai
 * - Contains transcript, cost, and call metadata
 * 
 * Architecture:
 * - Multi-tenant: Each tenant sees only their own calls
 * - Linked to VapiAssistant via assistantId
 * - Linked to VapiCallCostRecord for detailed cost tracking
 */
@Entity
@Table(name = "vapi_calls", 
       indexes = {
           @Index(name = "idx_vapi_call_tenant", columnList = "tenant_id"),
           @Index(name = "idx_vapi_call_assistant", columnList = "assistant_id"),
           @Index(name = "idx_vapi_call_vapi_id", columnList = "vapi_call_id"),
           @Index(name = "idx_vapi_call_status", columnList = "status"),
           @Index(name = "idx_vapi_call_created_at", columnList = "created_at")
       })
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VapiCall {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    /**
     * Tenant ID for multi-tenant isolation
     */
    @Column(name = "tenant_id", nullable = false, length = 100)
    private String tenantId;
    
    /**
     * Vapi.ai Call ID (returned by Vapi API)
     */
    @Column(name = "vapi_call_id", unique = true, length = 200)
    private String vapiCallId;
    
    /**
     * Assistant ID (links to VapiAssistant.id or VapiAssistant.vapiAssistantId)
     */
    @Column(name = "assistant_id", length = 200)
    private String assistantId;
    
    /**
     * Phone number that received the call (E.164 format)
     */
    @Column(name = "phone_number", length = 50)
    private String phoneNumber;
    
    /**
     * Customer phone number (E.164 format)
     */
    @Column(name = "customer_number", length = 50)
    private String customerNumber;
    
    /**
     * Call type: INBOUND, OUTBOUND, WEB
     */
    @Column(name = "call_type", length = 20)
    @Builder.Default
    private String callType = "OUTBOUND";
    
    /**
     * Call status: queued, ringing, in-progress, forwarding, ended
     */
    @Column(name = "status", length = 50)
    @Builder.Default
    private String status = "queued";
    
    /**
     * Call end reason: assistant-ended, customer-ended, assistant-forwarded, error, etc.
     */
    @Column(name = "end_reason", length = 100)
    private String endReason;
    
    /**
     * Call start time
     */
    @Column(name = "start_time")
    private LocalDateTime startTime;
    
    /**
     * Call end time
     */
    @Column(name = "end_time")
    private LocalDateTime endTime;
    
    /**
     * Call duration in seconds
     */
    @Column(name = "duration")
    private Integer duration;
    
    /**
     * Conversation transcript (JSON array of messages)
     * 
     * Example:
     * [
     *   {"role": "assistant", "message": "Hello, how can I help?", "timestamp": "2024-01-01T10:00:00Z"},
     *   {"role": "user", "message": "I want to book an appointment", "timestamp": "2024-01-01T10:00:05Z"}
     * ]
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "transcript", columnDefinition = "JSON")
    private List<Map<String, Object>> transcript;
    
    /**
     * Recording URL (if recording is enabled)
     */
    @Column(name = "recording_url", length = 500)
    private String recordingUrl;
    
    /**
     * Call cost (USD)
     */
    @Column(name = "cost", precision = 10, scale = 6)
    private BigDecimal cost;
    
    /**
     * Cost breakdown (JSON)
     * 
     * Example:
     * {
     *   "transport": 0.02,
     *   "transcriber": 0.05,
     *   "model": 0.15,
     *   "voice": 0.08,
     *   "total": 0.30
     * }
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "cost_breakdown", columnDefinition = "JSON")
    private Map<String, Object> costBreakdown;
    
    /**
     * Analysis data from Vapi.ai
     * 
     * Example:
     * {
     *   "summary": "Customer booked appointment for next Tuesday",
     *   "successEvaluation": "success",
     *   "structuredData": {...}
     * }
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "analysis", columnDefinition = "JSON")
    private Map<String, Object> analysis;
    
    /**
     * Full webhook payload from Vapi (for debugging)
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "webhook_payload", columnDefinition = "JSON")
    private Map<String, Object> webhookPayload;
    
    /**
     * Timestamps
     */
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
    }
    
    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }
}
