import { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Card from 'react-bootstrap/Card';
import Table from 'react-bootstrap/Table';
import Badge from 'react-bootstrap/Badge';
import ProgressBar from 'react-bootstrap/ProgressBar';
import { getSession, getUsersInSession, getDebrief, getObjectives, getSessionStats } from '../api/client';
import type { Session, User, DebriefRow, Participation, ObjectiveResults, SessionDebriefRow } from '../types';
import { REACT_EVENT_TYPE_LABELS, SessionType } from '../types';
import SessionTypeBadge from '../components/SessionTypeBadge';
import ScoreBadge from '../components/ScoreBadge';
import StatCard from '../components/StatCard';
import LoadingSpinner from '../components/LoadingSpinner';
import PrintHeader from '../components/PrintHeader';
import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer, Legend } from 'recharts';
import { useI18n } from '../i18n/context';
import type { TranslationKey } from '../i18n/translations';

function formatDuration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}m ${s}s`;
}

function formatDate(dateStr: string, lang: string): string {
  if (!dateStr) return '-';
  const d = new Date(dateStr);
  return d.toLocaleDateString(lang === 'fr' ? 'fr-FR' : 'en-US', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
}

const HIT_TYPE_COLORS: Record<string, string> = {
  'enemy': '#27ae60',
  'civilian': '#e74c3c',
  'police': '#f39c12',
  'object': '#6c757d',
  'target': '#4a90d9',
  'paperTarget': '#2980b9',
  'deadBody': '#95a5a6',
};

/** Maps French REACT_EVENT_TYPE_LABELS values to internal hit-type keys */
const FRENCH_LABEL_TO_HIT_KEY: Record<string, string> = {
  'Ennemi': 'enemy',
  'Civil': 'civilian',
  'Police': 'police',
  'Objet': 'object',
  'Cible': 'target',
  'Cible Papier': 'paperTarget',
  'Corps': 'deadBody',
};

/** Maps internal hit-type keys to TranslationKey */
const HIT_KEY_TO_TRANSLATION: Record<string, TranslationKey> = {
  'enemy': 'hitType.enemy',
  'civilian': 'hitType.civilian',
  'police': 'hitType.police',
  'object': 'hitType.object',
  'target': 'hitType.target',
  'paperTarget': 'hitType.paperTarget',
  'deadBody': 'hitType.deadBody',
};

function SessionDetail() {
  const { id } = useParams<{ id: string }>();
  const sessionId = Number(id);
  const { t, lang } = useI18n();

  const [session, setSession] = useState<Session | null>(null);
  const [users, setUsers] = useState<User[]>([]);
  const [debrief, setDebrief] = useState<DebriefRow[]>([]);
  const [objectives, setObjectives] = useState<Participation | null>(null);
  const [shotDetails, setShotDetails] = useState<SessionDebriefRow[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (!sessionId) return;

    Promise.all([
      getSession(sessionId).catch(() => null),
      getUsersInSession(sessionId).catch(() => []),
      getDebrief(sessionId).catch(() => []),
      getObjectives(sessionId).catch(() => null),
    ])
      .then(([sessionData, usersData, debriefData, objectivesData]) => {
        setSession(sessionData as Session | null);
        setUsers(usersData as User[]);
        setDebrief(debriefData as DebriefRow[]);
        setObjectives(objectivesData as Participation | null);

        // Load shot details for firerange/challenge types
        if (sessionData) {
          const st = sessionData.sessionTypeAsInt;
          if (st === SessionType.FireRange || st === SessionType.Challenge || st === SessionType.LongRange) {
            getSessionStats(sessionId, -1, st).then(setShotDetails);
          }
        }
      })
      .finally(() => setLoading(false));
  }, [sessionId]);

  if (loading) return <LoadingSpinner />;
  if (!session) return <p className="text-center text-muted-custom py-5">{t('session.notFound')}</p>;

  // Parse objectives
  let parsedObjectives: ObjectiveResults | null = null;
  if (objectives?.resultsAsString) {
    try {
      parsedObjectives = JSON.parse(objectives.resultsAsString);
    } catch {
      // ignore parse errors
    }
  }

  // Build hit distribution data from debrief
  const hitDistribution: Record<string, number> = {};
  debrief.forEach((row) => {
    if (row.nbEnemyHitsByUser > 0) hitDistribution['enemy'] = (hitDistribution['enemy'] || 0) + row.nbEnemyHitsByUser;
    if (row.nbCivilHitsByUser > 0) hitDistribution['civilian'] = (hitDistribution['civilian'] || 0) + row.nbCivilHitsByUser;
    if (row.nbPoliceHitsByUser > 0) hitDistribution['police'] = (hitDistribution['police'] || 0) + row.nbPoliceHitsByUser;
    if (row.nbObjectHitsByUser > 0) hitDistribution['object'] = (hitDistribution['object'] || 0) + row.nbObjectHitsByUser;
  });
  const hitChartData = Object.entries(hitDistribution).map(([key, value]) => ({
    name: t(HIT_KEY_TO_TRANSLATION[key]),
    value,
    color: HIT_TYPE_COLORS[key] || '#6c757d',
  }));

  // Map userId to username
  const userMap = new Map(users.map((u) => [u.id, u]));

  return (
    <>
      <PrintHeader subtitle={session.sessionName || session.scenarioName || `Session #${session.id}`} />

      <div className="d-flex justify-content-between align-items-center mb-3">
        <Link to="/sessions" className="text-muted-custom no-print">&larr; {t('session.backToSessions')}</Link>
        <button className="print-btn no-print" onClick={() => window.print()}>
          {t('print.btn')}
        </button>
      </div>

      {/* Session Header */}
      <Card className="data-card mb-4">
        <Card.Body>
          <Row className="align-items-center">
            <Col>
              <h3 className="mb-1">
                {session.sessionName || session.scenarioName || `Session #${session.id}`}
              </h3>
              <div className="d-flex gap-3 align-items-center flex-wrap">
                <SessionTypeBadge typeId={session.sessionTypeAsInt} />
                <span className="text-muted-custom">{formatDate(session.sessionDateAsString, lang)}</span>
                <span className="text-muted-custom">Map: {session.mapName || '-'}</span>
                <span className="text-muted-custom">Scenario: {session.scenarioName || '-'}</span>
              </div>
            </Col>
            <Col xs="auto">
              <ScoreBadge success={session.success} score={session.score} />
            </Col>
          </Row>
        </Card.Body>
      </Card>

      {/* KPI Cards */}
      <Row className="mb-4 g-3">
        <Col xs={6} md={2}>
          <StatCard title={t('session.score')} value={session.score} color="#4a90d9" />
        </Col>
        <Col xs={6} md={2}>
          <StatCard title={t('session.duration')} value={formatDuration(session.timeToFinish)} color="#9b59b6" />
        </Col>
        <Col xs={6} md={2}>
          <StatCard title={t('session.enemiesHit')} value={session.nbEnemyHit} color="#27ae60" />
        </Col>
        <Col xs={6} md={2}>
          <StatCard title={t('session.civiliansHit')} value={session.nbCivilsHit} color={session.nbCivilsHit > 0 ? '#e74c3c' : '#27ae60'} />
        </Col>
        <Col xs={6} md={2}>
          <StatCard title={t('session.damageTaken')} value={Math.round(session.damageTaken)} color="#f39c12" />
        </Col>
        <Col xs={6} md={2}>
          <StatCard title={t('session.participants')} value={users.length} color="#1abc9c" />
        </Col>
      </Row>

      {/* Participants */}
      <Card className="data-card mb-4">
        <Card.Body>
          <Card.Title>{t('session.participants')}</Card.Title>
          <Table hover responsive className="data-table mb-0">
            <thead>
              <tr>
                <th>{t('table.user')}</th>
                <th>{t('table.shotsFired')}</th>
                <th>{t('table.shotsMissed')}</th>
                <th>{t('table.enemiesHit')}</th>
                <th>{t('table.civiliansHit')}</th>
                <th>{t('table.avgPrecision')}</th>
                <th>{t('table.reactionTime')}</th>
                <th>{t('table.hitsReceivedIA')}</th>
                <th>{t('table.enemiesKilled')}</th>
                <th>{t('table.civiliansKilled')}</th>
              </tr>
            </thead>
            <tbody>
              {debrief.map((row, i) => {
                const user = userMap.get(row.userId);
                return (
                  <tr key={i}>
                    <td>
                      <Link to={`/users/${row.userId}`} className="table-link">
                        {user ? (user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : user.username) : `User #${row.userId}`}
                      </Link>
                    </td>
                    <td>{row.nbFiredShotsByUser}</td>
                    <td>{row.nbMissedShotsByUser}</td>
                    <td>{row.nbEnemyHitsByUser}</td>
                    <td className={row.nbCivilHitsByUser > 0 ? 'text-danger' : ''}>{row.nbCivilHitsByUser}</td>
                    <td>{row.averagePrecision != null ? `${(row.averagePrecision * 100).toFixed(1)}%` : '-'}</td>
                    <td>{row.averageReactionTime != null && row.averageReactionTime > 0 ? `${row.averageReactionTime.toFixed(0)} ms` : '-'}</td>
                    <td>{row.nbReceivedHitsFromEnemyIA ?? 0}</td>
                    <td>{row.totalEnemyKilled ?? 0}</td>
                    <td className={(row.totalCivilKilled ?? 0) > 0 ? 'text-danger' : ''}>{row.totalCivilKilled ?? 0}</td>
                  </tr>
                );
              })}
              {debrief.length === 0 && (
                <tr><td colSpan={10} className="text-center text-muted-custom">{t('noData')}</td></tr>
              )}
            </tbody>
          </Table>
        </Card.Body>
      </Card>

      <Row className="mb-4 g-3">
        {/* Objectives */}
        {parsedObjectives && (
          <Col md={6}>
            <Card className="data-card h-100">
              <Card.Body>
                <Card.Title>{t('session.objectives')}</Card.Title>
                {Object.entries(parsedObjectives).map(([key, obj]) => {
                  if (!obj || typeof obj !== 'object') return null;
                  const pct = obj.maxScore > 0 ? (obj.score / obj.maxScore) * 100 : 0;
                  return (
                    <div key={key} className="mb-3">
                      <div className="d-flex justify-content-between mb-1">
                        <span>{t(`obj.${key}` as TranslationKey)}</span>
                        <span>
                          {obj.score}/{obj.maxScore}
                          {obj.success !== undefined && (
                            <Badge bg={obj.success ? 'success' : 'danger'} className="ms-2">
                              {obj.success ? 'OK' : 'X'}
                            </Badge>
                          )}
                        </span>
                      </div>
                      <ProgressBar
                        now={pct}
                        variant={obj.success ? 'success' : 'danger'}
                        className="objective-bar"
                      />
                    </div>
                  );
                })}
              </Card.Body>
            </Card>
          </Col>
        )}

        {/* Hit Distribution Chart */}
        {hitChartData.length > 0 && (
          <Col md={parsedObjectives ? 6 : 12}>
            <Card className="chart-card h-100">
              <Card.Body>
                <Card.Title>{t('session.hitDistribution')}</Card.Title>
                <ResponsiveContainer width="100%" height={250}>
                  <PieChart>
                    <Pie data={hitChartData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} label>
                      {hitChartData.map((entry, index) => (
                        <Cell key={index} fill={entry.color} />
                      ))}
                    </Pie>
                    <Tooltip contentStyle={{ backgroundColor: '#1a1a2e', border: '1px solid #333' }} />
                    <Legend />
                  </PieChart>
                </ResponsiveContainer>
              </Card.Body>
            </Card>
          </Col>
        )}
      </Row>

      {/* Shot Details for FireRange/Challenge */}
      {shotDetails.length > 0 && (
        <Card className="data-card mb-4">
          <Card.Body>
            <Card.Title>{t('session.shotDetails')}</Card.Title>
            <Table hover responsive className="data-table mb-0" size="sm">
              <thead>
                <tr>
                  <th>{t('shot.index')}</th>
                  <th>{t('shot.shooter')}</th>
                  <th>{t('shot.impactType')}</th>
                  <th>{t('shot.target')}</th>
                  <th>{t('shot.boneZone')}</th>
                  <th>{t('shot.precision')}</th>
                  <th>{t('shot.distance')}</th>
                  <th>{t('shot.reaction')}</th>
                  <th>{t('shot.killed')}</th>
                  <th>{t('shot.time')}</th>
                </tr>
              </thead>
              <tbody>
                {shotDetails.map((shot, i) => {
                  const frenchLabel = REACT_EVENT_TYPE_LABELS[shot.reactTypeId] || '';
                  const hitKey = FRENCH_LABEL_TO_HIT_KEY[frenchLabel] || '';
                  const translatedLabel = hitKey && HIT_KEY_TO_TRANSLATION[hitKey]
                    ? t(HIT_KEY_TO_TRANSLATION[hitKey])
                    : shot.reactType || '-';
                  const badgeColor = HIT_TYPE_COLORS[hitKey] || '#6c757d';
                  return (
                    <tr key={i}>
                      <td>{shot.shotIndex}</td>
                      <td>{shot.shooterName || `#${shot.shooterId}`}</td>
                      <td>
                        <Badge bg="secondary" style={{ backgroundColor: badgeColor }}>
                          {translatedLabel}
                        </Badge>
                      </td>
                      <td>{shot.targetName || shot.targetUserName || '-'}</td>
                      <td>{shot.targetBoneName || shot.hitLocationTag || '-'}</td>
                      <td>{shot.hitPrecision != null ? `${(shot.hitPrecision * 100).toFixed(1)}%` : '-'}</td>
                      <td>{shot.hitTargetDistance != null && shot.hitTargetDistance > 0 ? `${shot.hitTargetDistance.toFixed(1)}m` : '-'}</td>
                      <td>{shot.reactionTime != null && shot.reactionTime > 0 ? `${shot.reactionTime.toFixed(0)}ms` : '-'}</td>
                      <td>{shot.targetKilled ? <Badge bg="danger">{t('badge.killed')}</Badge> : '-'}</td>
                      <td>{shot.timeStamp != null ? `${shot.timeStamp.toFixed(1)}s` : '-'}</td>
                    </tr>
                  );
                })}
              </tbody>
            </Table>
          </Card.Body>
        </Card>
      )}
    </>
  );
}

export default SessionDetail;
