import { useState } from 'react'
import { useMutation, useQuery } from '@tanstack/react-query'
import {
  Box,
  Paper,
  Typography,
  Button,
  TextField,
  Grid,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Alert,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Card,
  CardContent,
} from '@mui/material'
import { backtestingApi } from '../api/backtesting'
import { strategiesApi } from '../api/strategies'
import { reportingApi } from '../api/reporting'
import { BacktestRequest, StrategyResponse } from '../types'
import { useSnackbar } from '../contexts/SnackbarContext'
import HelpTooltip from '../components/HelpTooltip'
import InfoCard from '../components/InfoCard'
import OperationsPanel from '../components/OperationsPanel'
import ProgressOverlay from '../components/ProgressOverlay'
import { settingsApi } from '../api/settings'
import { formatDate } from '../utils/formatters'

export default function BacktestPage() {
  const { showError, showSuccess } = useSnackbar()
  const [strategyId, setStrategyId] = useState('')
  const [symbol, setSymbol] = useState('BTC/USD')
  const [exchange, setExchange] = useState('coinbase')
  const [timeframe, setTimeframe] = useState('1h')
  const [startDate, setStartDate] = useState('')
  const [endDate, setEndDate] = useState('')
  const [initialCapital, setInitialCapital] = useState('100')
  const [slippage, setSlippage] = useState('0.1')
  const [feeRate, setFeeRate] = useState('0.1')
  const [backtestResults, setBacktestResults] = useState<any>(null)

  const { data: strategies, isLoading: strategiesLoading } = useQuery({
    queryKey: ['strategies'],
    queryFn: () => strategiesApi.listStrategies(),
  })

  const { data: generalSettings } = useQuery({
    queryKey: ['general-settings'],
    queryFn: () => settingsApi.getGeneralSettings(),
  })

  const backtestMutation = useMutation({
    mutationFn: backtestingApi.runBacktest,
    onSuccess: (data) => {
      setBacktestResults(data.results)
      showSuccess('Backtest completed successfully')
    },
    onError: (error: any) => {
      showError(error?.response?.data?.detail || error?.message || 'Backtest failed')
    },
  })

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (!strategyId) {
      showError('Please select a strategy')
      return
    }
    const request: BacktestRequest = {
      strategy_id: parseInt(strategyId),
      symbol,
      exchange,
      timeframe,
      start_date: new Date(startDate).toISOString(),
      end_date: new Date(endDate).toISOString(),
      initial_capital: parseFloat(initialCapital),
      slippage: parseFloat(slippage) / 100, // Convert percentage to decimal
      fee_rate: parseFloat(feeRate) / 100, // Convert percentage to decimal
    }
    backtestMutation.mutate(request)
  }

  return (
    <Box>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
        <Typography variant="h4">Backtesting</Typography>
        <HelpTooltip title="Test your strategies on historical data to evaluate performance before live trading" />
      </Box>

      <InfoCard title="Parameter Optimization" collapsible>
        Parameter optimization allows you to find the best strategy parameters automatically.
        This feature requires backend API support for optimization methods (Grid Search, Genetic Algorithm, Bayesian Optimization).
        The optimization UI can be added once the backend endpoints are available.
      </InfoCard>

      <Paper sx={{ p: 3, position: 'relative' }}>
        {backtestMutation.isPending && (
          <ProgressOverlay
            message="Running backtest... This may take a moment."
            variant="indeterminate"
          />
        )}
        <form onSubmit={handleSubmit}>
          <Grid container spacing={3}>
            <Grid item xs={12} md={6}>
              <FormControl fullWidth required>
                <InputLabel>Strategy</InputLabel>
                <Select
                  value={strategyId}
                  label="Strategy"
                  onChange={(e) => setStrategyId(e.target.value)}
                  disabled={strategiesLoading}
                >
                  {strategiesLoading ? (
                    <MenuItem disabled>Loading strategies...</MenuItem>
                  ) : strategies && strategies.length > 0 ? (
                    strategies.map((strategy: StrategyResponse) => (
                      <MenuItem key={strategy.id} value={strategy.id.toString()}>
                        {strategy.name} ({strategy.strategy_type})
                      </MenuItem>
                    ))
                  ) : (
                    <MenuItem disabled>No strategies available</MenuItem>
                  )}
                </Select>
              </FormControl>
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Symbol"
                value={symbol}
                onChange={(e) => setSymbol(e.target.value)}
                required
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Exchange"
                value={exchange}
                onChange={(e) => setExchange(e.target.value)}
                required
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <FormControl fullWidth>
                <InputLabel>Timeframe</InputLabel>
                <Select value={timeframe} onChange={(e) => setTimeframe(e.target.value)}>
                  <MenuItem value="1m">1 Minute</MenuItem>
                  <MenuItem value="5m">5 Minutes</MenuItem>
                  <MenuItem value="15m">15 Minutes</MenuItem>
                  <MenuItem value="1h">1 Hour</MenuItem>
                  <MenuItem value="4h">4 Hours</MenuItem>
                  <MenuItem value="1d">1 Day</MenuItem>
                </Select>
              </FormControl>
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Start Date"
                type="date"
                value={startDate}
                onChange={(e) => setStartDate(e.target.value)}
                required
                InputLabelProps={{ shrink: true }}
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="End Date"
                type="date"
                value={endDate}
                onChange={(e) => setEndDate(e.target.value)}
                required
                InputLabelProps={{ shrink: true }}
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Initial Capital ($)"
                type="number"
                value={initialCapital}
                onChange={(e) => setInitialCapital(e.target.value)}
                required
                inputProps={{ step: '0.01', min: 0 }}
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Slippage (%)"
                type="number"
                value={slippage}
                onChange={(e) => setSlippage(e.target.value)}
                required
                inputProps={{ step: '0.01', min: 0, max: 10 }}
                helperText="Percentage slippage per trade (e.g., 0.1 for 0.1%)"
              />
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="Fee Rate (%)"
                type="number"
                value={feeRate}
                onChange={(e) => setFeeRate(e.target.value)}
                required
                inputProps={{ step: '0.01', min: 0, max: 10 }}
                helperText="Trading fee percentage (e.g., 0.1 for 0.1%)"
              />
            </Grid>
            <Grid item xs={12}>
              <Button
                type="submit"
                variant="contained"
                disabled={backtestMutation.isPending || !strategyId}
                fullWidth
              >
                {backtestMutation.isPending ? 'Running Backtest...' : 'Run Backtest'}
              </Button>
            </Grid>
          </Grid>
        </form>

        {backtestMutation.isError && (
          <Alert severity="error" sx={{ mt: 2 }}>
            {backtestMutation.error instanceof Error
              ? backtestMutation.error.message
              : 'Backtest failed'}
          </Alert>
        )}

        {/* Operations Panel */}
        {backtestMutation.isPending && (
          <Box sx={{ mt: 3 }}>
            <OperationsPanel
              operations={[
                {
                  id: 'backtest-running',
                  type: 'backtest',
                  name: `Backtesting ${symbol} from ${startDate} to ${endDate}`,
                  status: 'running',
                  startTime: new Date(),
                },
              ]}
            />
          </Box>
        )}

        {backtestMutation.isSuccess && backtestResults && (
          <Box sx={{ mt: 3 }}>
            <Alert severity="success" sx={{ mb: 2 }}>
              Backtest completed successfully!
            </Alert>

            {/* Results Metrics */}
            <Paper sx={{ p: 3, mb: 3 }}>
              <Typography variant="h6" gutterBottom>
                Performance Metrics
              </Typography>
              <Grid container spacing={2}>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Total Return
                      </Typography>
                      <Typography
                        variant="h5"
                        sx={{
                          color: (backtestResults.total_return || 0) >= 0 ? 'success.main' : 'error.main',
                        }}
                      >
                        {((backtestResults.total_return || 0) * 100).toFixed(2)}%
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Sharpe Ratio
                      </Typography>
                      <Typography variant="h5">
                        {(backtestResults.sharpe_ratio || 0).toFixed(2)}
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Sortino Ratio
                      </Typography>
                      <Typography variant="h5">
                        {(backtestResults.sortino_ratio || 0).toFixed(2)}
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Max Drawdown
                      </Typography>
                      <Typography
                        variant="h5"
                        sx={{
                          color: (backtestResults.max_drawdown || 0) < 0 ? 'error.main' : 'text.primary',
                        }}
                      >
                        {((backtestResults.max_drawdown || 0) * 100).toFixed(2)}%
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Win Rate
                      </Typography>
                      <Typography variant="h5">
                        {((backtestResults.win_rate || 0) * 100).toFixed(1)}%
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Total Trades
                      </Typography>
                      <Typography variant="h5">
                        {backtestResults.total_trades || 0}
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Final Value
                      </Typography>
                      <Typography variant="h5">
                        ${(backtestResults.final_value || 0).toFixed(2)}
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                  <Card variant="outlined">
                    <CardContent>
                      <Typography color="textSecondary" gutterBottom variant="body2">
                        Initial Capital
                      </Typography>
                      <Typography variant="h5">
                        ${(backtestResults.initial_capital || parseFloat(initialCapital)).toFixed(2)}
                      </Typography>
                    </CardContent>
                  </Card>
                </Grid>
              </Grid>
            </Paper>

            {/* Export Buttons */}
            <Paper sx={{ p: 2, mb: 3 }}>
              <Box sx={{ display: 'flex', gap: 2 }}>
                <Button
                  variant="outlined"
                  onClick={async () => {
                    try {
                      const blob = await reportingApi.exportBacktestCSV(backtestResults)
                      const url = window.URL.createObjectURL(blob)
                      const a = document.createElement('a')
                      a.href = url
                      a.download = `backtest_results_${new Date().toISOString().split('T')[0]}.csv`
                      document.body.appendChild(a)
                      a.click()
                      window.URL.revokeObjectURL(url)
                      document.body.removeChild(a)
                    } catch (error) {
                      showError('Failed to export CSV: ' + (error instanceof Error ? error.message : 'Unknown error'))
                    }
                  }}
                >
                  Export CSV
                </Button>
                <Button
                  variant="outlined"
                  onClick={async () => {
                    try {
                      const blob = await reportingApi.exportBacktestPDF(backtestResults)
                      const url = window.URL.createObjectURL(blob)
                      const a = document.createElement('a')
                      a.href = url
                      a.download = `backtest_report_${new Date().toISOString().split('T')[0]}.pdf`
                      document.body.appendChild(a)
                      a.click()
                      window.URL.revokeObjectURL(url)
                      document.body.removeChild(a)
                    } catch (error) {
                      showError('Failed to export PDF: ' + (error instanceof Error ? error.message : 'Unknown error'))
                    }
                  }}
                >
                  Export PDF
                </Button>
              </Box>
            </Paper>

            {/* Trades Table */}
            {backtestResults.trades && backtestResults.trades.length > 0 && (
              <Paper sx={{ p: 3 }}>
                <Typography variant="h6" gutterBottom>
                  Trades ({backtestResults.trades.length})
                </Typography>
                <TableContainer>
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Time</TableCell>
                        <TableCell>Side</TableCell>
                        <TableCell align="right">Price</TableCell>
                        <TableCell align="right">Quantity</TableCell>
                        <TableCell align="right">Value</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {backtestResults.trades.slice(0, 100).map((trade: any, index: number) => (
                        <TableRow key={index}>
                          <TableCell>
                            {formatDate(trade.timestamp || '', generalSettings)}
                          </TableCell>
                          <TableCell>
                            <Typography
                              variant="body2"
                              sx={{
                                color: trade.side === 'buy' ? 'success.main' : 'error.main',
                                fontWeight: 'bold',
                              }}
                            >
                              {trade.side?.toUpperCase() || 'N/A'}
                            </Typography>
                          </TableCell>
                          <TableCell align="right">${(trade.price || 0).toFixed(2)}</TableCell>
                          <TableCell align="right">{(trade.quantity || 0).toFixed(8)}</TableCell>
                          <TableCell align="right">
                            ${((trade.price || 0) * (trade.quantity || 0)).toFixed(2)}
                          </TableCell>
                        </TableRow>
                      ))}
                      {backtestResults.trades.length > 100 && (
                        <TableRow>
                          <TableCell colSpan={5} align="center">
                            <Typography variant="body2" color="text.secondary">
                              Showing first 100 trades of {backtestResults.trades.length} total
                            </Typography>
                          </TableCell>
                        </TableRow>
                      )}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Paper>
            )}
          </Box>
        )}
      </Paper>
    </Box>
  )
}
