import { useEffect, useRef, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faWaveformLines, faSpinner, faPlay, faPause } from '@fortawesome/pro-duotone-svg-icons';
import { Badge } from '@/components/base/badges/badges';
import { Button } from '@/components/base/buttons/button';
import { SlideoutMenu } from '@/components/application/slideout-menus/slideout-menu';
import { apiClient } from '@/lib/api-client';
import { formatPhone, formatDateOnly } from '@/lib/format';
import { cx } from '@/utils/cx';

type Utterance = {
    speaker: number;
    start: number;
    end: number;
    text: string;
};

type Insights = {
    keyTopics: string[];
    actionItems: string[];
    coachingNotes: string[];
    complianceFlags: string[];
    patientSatisfaction: string;
    callOutcome: string;
};

type Analysis = {
    transcript: Utterance[];
    summary: string | null;
    sentiment: 'positive' | 'neutral' | 'negative' | 'mixed';
    sentimentScore: number;
    insights: Insights;
    durationSec: number;
};

const sentimentConfig = {
    positive: { label: 'Positive', color: 'success' as const },
    neutral: { label: 'Neutral', color: 'gray' as const },
    negative: { label: 'Negative', color: 'error' as const },
    mixed: { label: 'Mixed', color: 'warning' as const },
};

const formatTimestamp = (sec: number): string => {
    const m = Math.floor(sec / 60);
    const s = Math.floor(sec % 60);
    return `${m}:${s.toString().padStart(2, '0')}`;
};

const formatDuration = (sec: number | null): string => {
    if (!sec) return '';
    const m = Math.floor(sec / 60);
    const s = sec % 60;
    return `${m}:${s.toString().padStart(2, '0')}`;
};

// Inline audio player for the slideout header
const SlideoutPlayer = ({ url }: { url: string }) => {
    const audioRef = useRef<HTMLAudioElement>(null);
    const [playing, setPlaying] = useState(false);

    const toggle = () => {
        if (!audioRef.current) return;
        if (playing) { audioRef.current.pause(); } else { audioRef.current.play(); }
        setPlaying(!playing);
    };

    return (
        <div className="flex items-center gap-2">
            <button
                onClick={toggle}
                className="flex size-8 items-center justify-center rounded-full bg-brand-solid text-white hover:opacity-90 transition duration-100 ease-linear"
            >
                <FontAwesomeIcon icon={playing ? faPause : faPlay} className="size-3.5" />
            </button>
            <span className="text-xs text-tertiary">{playing ? 'Playing...' : 'Play recording'}</span>
            <audio ref={audioRef} src={url} onEnded={() => setPlaying(false)} />
        </div>
    );
};

// Insights section rendered after analysis completes
const InsightsSection = ({ label, children }: { label: string; children: React.ReactNode }) => (
    <div className="rounded-lg bg-secondary p-3">
        <span className="text-xs font-semibold text-tertiary uppercase tracking-wider">{label}</span>
        <div className="mt-1">{children}</div>
    </div>
);

type RecordingAnalysisSlideoutProps = {
    isOpen: boolean;
    onOpenChange: (open: boolean) => void;
    recordingUrl: string;
    callId: string;
    agentName: string | null;
    callerNumber: string | null;
    direction: string | null;
    startedAt: string | null;
    durationSec: number | null;
    disposition: string | null;
};

export const RecordingAnalysisSlideout = ({
    isOpen,
    onOpenChange,
    recordingUrl,
    callId,
    agentName,
    callerNumber,
    direction,
    startedAt,
    durationSec,
    disposition,
}: RecordingAnalysisSlideoutProps) => {
    const [analysis, setAnalysis] = useState<Analysis | null>(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const hasTriggered = useRef(false);

    // Auto-trigger analysis when the slideout opens
    useEffect(() => {
        if (!isOpen || hasTriggered.current) return;
        hasTriggered.current = true;

        setLoading(true);
        setError(null);
        apiClient.post<Analysis>('/api/recordings/analyze', { recordingUrl, callId })
            .then((result) => setAnalysis(result))
            .catch((err: any) => setError(err.message ?? 'Analysis failed'))
            .finally(() => setLoading(false));
    }, [isOpen, recordingUrl, callId]);

    const dirLabel = direction === 'INBOUND' ? 'Inbound' : 'Outbound';
    const dirColor = direction === 'INBOUND' ? 'blue' : 'brand';
    const formattedPhone = callerNumber
        ? formatPhone({ number: callerNumber, callingCode: '+91' })
        : null;

    return (
        <SlideoutMenu isOpen={isOpen} onOpenChange={onOpenChange} isDismissable>
            {({ close }) => (
                <>
                    <SlideoutMenu.Header onClose={close}>
                        <div className="flex flex-col gap-1.5 pr-8">
                            <h2 className="text-lg font-semibold text-primary">Call Analysis</h2>
                            <div className="flex flex-wrap items-center gap-2 text-sm text-tertiary">
                                <Badge size="sm" color={dirColor} type="pill-color">{dirLabel}</Badge>
                                {agentName && <span>{agentName}</span>}
                                {formattedPhone && (
                                    <>
                                        <span className="text-quaternary">-</span>
                                        <span>{formattedPhone}</span>
                                    </>
                                )}
                            </div>
                            <div className="flex flex-wrap items-center gap-3 text-xs text-quaternary">
                                {startedAt && <span>{formatDateOnly(startedAt)}</span>}
                                {durationSec != null && durationSec > 0 && <span>{formatDuration(durationSec)}</span>}
                                {disposition && (
                                    <Badge size="sm" color="gray" type="pill-color">
                                        {disposition.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, c => c.toUpperCase())}
                                    </Badge>
                                )}
                            </div>
                            <div className="mt-1">
                                <SlideoutPlayer url={recordingUrl} />
                            </div>
                        </div>
                    </SlideoutMenu.Header>

                    <SlideoutMenu.Content>
                        {loading && (
                            <div className="flex flex-col items-center justify-center gap-3 py-16">
                                <FontAwesomeIcon icon={faSpinner} className="size-6 animate-spin text-brand-secondary" />
                                <p className="text-sm text-tertiary">Analyzing recording...</p>
                                <p className="text-xs text-quaternary">Transcribing and generating insights</p>
                            </div>
                        )}

                        {error && !loading && (
                            <div className="flex flex-col items-center gap-3 py-12">
                                <p className="text-sm text-tertiary">Transcription is temporarily unavailable. Please try again.</p>
                                <Button
                                    size="sm"
                                    color="secondary"
                                    iconLeading={<FontAwesomeIcon icon={faWaveformLines} data-icon className="size-3.5" />}
                                    onClick={() => {
                                        hasTriggered.current = false;
                                        setLoading(true);
                                        setError(null);
                                        apiClient.post<Analysis>('/api/recordings/analyze', { recordingUrl, callId })
                                            .then((result) => setAnalysis(result))
                                            .catch((err: any) => setError(err.message ?? 'Analysis failed'))
                                            .finally(() => setLoading(false));
                                    }}
                                >
                                    Retry
                                </Button>
                            </div>
                        )}

                        {analysis && !loading && (
                            <AnalysisResults analysis={analysis} />
                        )}
                    </SlideoutMenu.Content>
                </>
            )}
        </SlideoutMenu>
    );
};

// Separated analysis results display for readability
const AnalysisResults = ({ analysis }: { analysis: Analysis }) => {
    const sentCfg = sentimentConfig[analysis.sentiment];

    return (
        <div className="flex flex-col gap-4">
            {/* Sentiment + topics */}
            <div className="flex flex-wrap items-center gap-2">
                <Badge size="sm" color={sentCfg.color} type="pill-color">{sentCfg.label}</Badge>
                {analysis.insights.keyTopics.slice(0, 4).map((topic) => (
                    <Badge key={topic} size="sm" color="gray" type="pill-color">{topic}</Badge>
                ))}
            </div>

            {/* Summary */}
            {analysis.summary && (
                <div className="rounded-lg bg-secondary p-3">
                    <span className="text-xs font-semibold text-tertiary uppercase tracking-wider">Summary</span>
                    <p className="mt-1 text-sm text-primary">{analysis.summary}</p>
                </div>
            )}

            {/* Call outcome */}
            <div className="rounded-lg bg-brand-secondary p-3">
                <span className="text-xs font-semibold text-brand-tertiary uppercase tracking-wider">Call Outcome</span>
                <p className="mt-1 text-sm text-primary_on-brand font-medium">{analysis.insights.callOutcome}</p>
            </div>

            {/* Insights grid */}
            <div className="grid grid-cols-1 gap-3">
                <InsightsSection label="Patient Satisfaction">
                    <p className="text-sm text-primary">{analysis.insights.patientSatisfaction}</p>
                </InsightsSection>

                {analysis.insights.actionItems.length > 0 && (
                    <InsightsSection label="Action Items">
                        <ul className="space-y-0.5">
                            {analysis.insights.actionItems.map((item, i) => (
                                <li key={i} className="text-sm text-primary">- {item}</li>
                            ))}
                        </ul>
                    </InsightsSection>
                )}

                {analysis.insights.coachingNotes.length > 0 && (
                    <InsightsSection label="Coaching Notes">
                        <ul className="space-y-0.5">
                            {analysis.insights.coachingNotes.map((note, i) => (
                                <li key={i} className="text-sm text-primary">- {note}</li>
                            ))}
                        </ul>
                    </InsightsSection>
                )}

                {analysis.insights.complianceFlags.length > 0 && (
                    <div className="rounded-lg bg-error-secondary p-3">
                        <span className="text-xs font-semibold text-error-primary uppercase tracking-wider">Compliance Flags</span>
                        <ul className="mt-1 space-y-0.5">
                            {analysis.insights.complianceFlags.map((flag, i) => (
                                <li key={i} className="text-sm text-error-primary">- {flag}</li>
                            ))}
                        </ul>
                    </div>
                )}
            </div>

            {/* Transcript */}
            {analysis.transcript.length > 0 && (
                <div>
                    <span className="text-xs font-semibold text-tertiary uppercase tracking-wider">Transcript</span>
                    <div className="mt-2 space-y-2 rounded-lg bg-secondary p-3">
                        {analysis.transcript.map((u, i) => {
                            const isAgent = u.speaker === 0;
                            return (
                                <div key={i} className="flex gap-2">
                                    <span className="shrink-0 text-xs text-quaternary tabular-nums w-10">{formatTimestamp(u.start)}</span>
                                    <span className={cx(
                                        'text-xs font-semibold shrink-0 w-16',
                                        isAgent ? 'text-brand-secondary' : 'text-success-primary',
                                    )}>
                                        {isAgent ? 'Agent' : 'Customer'}
                                    </span>
                                    <span className="text-sm text-primary">{u.text}</span>
                                </div>
                            );
                        })}
                    </div>
                </div>
            )}
        </div>
    );
};
