/**
 * Gas Estimator Tool - Interactive gas estimation for transactions and contracts.
 */

import { useState, useMemo } from 'react';
import {
  Fuel,
  Calculator,
  Zap,
  Shield,
  Clock,
  Info,
  ArrowRight,
  AlertTriangle,
} from 'lucide-react';
import { useGasCosts, useGasEstimate } from '../hooks/useApi';
import type { GasEstimateRequest } from '../lib/types';

/**
 * Validate a Synor address format
 * Addresses should be bech32 encoded with 'synor1' or 'tsynor1' prefix
 */
function validateSynorAddress(address: string): { valid: boolean; error?: string } {
  if (!address) {
    return { valid: false };
  }

  // Check prefix
  const hasValidPrefix = address.startsWith('synor1') || address.startsWith('tsynor1');
  if (!hasValidPrefix) {
    return { valid: false, error: 'Address must start with "synor1" or "tsynor1"' };
  }

  // Check length (bech32 addresses are typically 42-62 chars for synor)
  const minLength = address.startsWith('tsynor1') ? 40 : 39;
  const maxLength = 90;
  if (address.length < minLength || address.length > maxLength) {
    return { valid: false, error: `Invalid address length (expected ${minLength}-${maxLength} chars)` };
  }

  // Check for valid bech32 characters (lowercase alphanumeric except 1, b, i, o)
  const bech32Chars = /^(synor1|tsynor1)[ac-hj-np-z02-9]+$/;
  if (!bech32Chars.test(address)) {
    return { valid: false, error: 'Address contains invalid characters' };
  }

  return { valid: true };
}

/**
 * Validate hex data
 */
function validateHexData(data: string): { valid: boolean; error?: string } {
  if (!data) {
    return { valid: true }; // Empty is valid (optional field)
  }

  if (!data.startsWith('0x')) {
    return { valid: false, error: 'Hex data must start with "0x"' };
  }

  const hexPattern = /^0x[a-fA-F0-9]*$/;
  if (!hexPattern.test(data)) {
    return { valid: false, error: 'Invalid hex characters' };
  }

  return { valid: true };
}

export default function GasEstimator() {
  const { data: gasCosts, isLoading: costsLoading } = useGasCosts();

  // Form state for custom estimation
  const [toAddress, setToAddress] = useState('');
  const [fromAddress, setFromAddress] = useState('');
  const [callData, setCallData] = useState('');
  const [value, setValue] = useState('0');

  // Validate inputs
  const toValidation = useMemo(() => validateSynorAddress(toAddress), [toAddress]);
  const fromValidation = useMemo(() =>
    fromAddress ? validateSynorAddress(fromAddress) : { valid: true },
    [fromAddress]
  );
  const dataValidation = useMemo(() => validateHexData(callData), [callData]);

  // Only build request when all validations pass
  const isFormValid = toValidation.valid && fromValidation.valid && dataValidation.valid;

  // Build request only when we have a valid to address
  const estimateRequest: GasEstimateRequest | null = isFormValid && toAddress
    ? {
        to: toAddress,
        from: fromAddress || undefined,
        data: callData || undefined,
        value: value ? parseInt(value, 10) : undefined,
      }
    : null;

  const {
    data: gasEstimate,
    isLoading: estimating,
    error: estimateError,
  } = useGasEstimate(estimateRequest, { enabled: !!toAddress });

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="relative">
        <div className="absolute -top-10 left-0 w-[300px] h-[150px] bg-amber-500/10 rounded-full blur-[80px] pointer-events-none" />

        <div className="relative flex items-center gap-4">
          <div className="p-3 rounded-xl bg-gradient-to-br from-amber-500/20 to-orange-500/20 border border-amber-500/30">
            <Fuel size={28} className="text-amber-400" />
          </div>
          <div>
            <h1 className="text-2xl md:text-3xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
              Gas Estimator
            </h1>
            <p className="text-gray-400 text-sm mt-1">
              Estimate transaction fees and gas usage
            </p>
          </div>
        </div>
      </div>

      {/* Gas Cost Reference */}
      <div className="card">
        <div className="card-header flex items-center gap-2">
          <Info size={18} className="text-synor-400" />
          <h2 className="font-semibold">Gas Cost Reference</h2>
        </div>
        {costsLoading ? (
          <div className="p-4 text-gray-400">Loading gas costs...</div>
        ) : gasCosts ? (
          <div className="grid md:grid-cols-3 gap-4 p-4">
            {/* Basic Operations */}
            <div className="space-y-3">
              <h3 className="text-sm font-medium text-gray-400 flex items-center gap-2">
                <ArrowRight size={14} />
                Basic Operations
              </h3>
              <div className="space-y-2">
                <GasCostRow label="Transfer" value={gasCosts.transfer} />
                <GasCostRow label="Contract Call (base)" value={gasCosts.contractCallBase} />
                <GasCostRow label="Contract Deploy (base)" value={gasCosts.contractDeployBase} />
              </div>
            </div>

            {/* Storage */}
            <div className="space-y-3">
              <h3 className="text-sm font-medium text-gray-400 flex items-center gap-2">
                <Clock size={14} />
                Storage Operations
              </h3>
              <div className="space-y-2">
                <GasCostRow label="SSTORE (write)" value={gasCosts.storage.sstore} />
                <GasCostRow label="SLOAD (read)" value={gasCosts.storage.sload} />
                <GasCostRow label="Memory (per word)" value={gasCosts.memory.perWord} />
              </div>
            </div>

            {/* Cryptography */}
            <div className="space-y-3">
              <h3 className="text-sm font-medium text-gray-400 flex items-center gap-2">
                <Shield size={14} />
                Signature Verification
              </h3>
              <div className="space-y-2">
                <GasCostRow label="Ed25519" value={gasCosts.signature.ed25519} />
                <GasCostRow
                  label="Dilithium3 (PQC)"
                  value={gasCosts.signature.dilithium}
                  highlight
                />
              </div>
            </div>
          </div>
        ) : (
          <div className="p-4 text-gray-400">Failed to load gas costs</div>
        )}
      </div>

      {/* Custom Gas Estimation Form */}
      <div className="card">
        <div className="card-header flex items-center gap-2">
          <Calculator size={18} className="text-synor-400" />
          <h2 className="font-semibold">Estimate Gas</h2>
        </div>
        <div className="p-4 space-y-4">
          <div className="grid md:grid-cols-2 gap-4">
            {/* To Address */}
            <div>
              <label className="block text-sm text-gray-400 mb-1">
                To Address <span className="text-red-400">*</span>
              </label>
              <input
                type="text"
                value={toAddress}
                onChange={(e) => setToAddress(e.target.value.toLowerCase())}
                placeholder="synor1..."
                className={`w-full px-3 py-2 rounded-lg bg-gray-800/50 border focus:outline-none text-sm font-mono ${
                  toAddress && !toValidation.valid
                    ? 'border-red-500 focus:border-red-500'
                    : 'border-gray-700 focus:border-synor-500'
                }`}
              />
              {toAddress && toValidation.error && (
                <div className="flex items-center gap-1 mt-1 text-xs text-red-400">
                  <AlertTriangle size={12} />
                  {toValidation.error}
                </div>
              )}
            </div>

            {/* From Address */}
            <div>
              <label className="block text-sm text-gray-400 mb-1">
                From Address (optional)
              </label>
              <input
                type="text"
                value={fromAddress}
                onChange={(e) => setFromAddress(e.target.value.toLowerCase())}
                placeholder="synor1..."
                className={`w-full px-3 py-2 rounded-lg bg-gray-800/50 border focus:outline-none text-sm font-mono ${
                  fromAddress && !fromValidation.valid
                    ? 'border-red-500 focus:border-red-500'
                    : 'border-gray-700 focus:border-synor-500'
                }`}
              />
              {fromAddress && fromValidation.error && (
                <div className="flex items-center gap-1 mt-1 text-xs text-red-400">
                  <AlertTriangle size={12} />
                  {fromValidation.error}
                </div>
              )}
            </div>
          </div>

          {/* Call Data */}
          <div>
            <label className="block text-sm text-gray-400 mb-1">
              Call Data (hex, optional)
            </label>
            <input
              type="text"
              value={callData}
              onChange={(e) => setCallData(e.target.value)}
              placeholder="0x..."
              className={`w-full px-3 py-2 rounded-lg bg-gray-800/50 border focus:outline-none text-sm font-mono ${
                callData && !dataValidation.valid
                  ? 'border-red-500 focus:border-red-500'
                  : 'border-gray-700 focus:border-synor-500'
              }`}
            />
            {callData && dataValidation.error && (
              <div className="flex items-center gap-1 mt-1 text-xs text-red-400">
                <AlertTriangle size={12} />
                {dataValidation.error}
              </div>
            )}
          </div>

          {/* Value */}
          <div>
            <label className="block text-sm text-gray-400 mb-1">
              Value (sompi)
            </label>
            <input
              type="number"
              value={value}
              onChange={(e) => setValue(e.target.value)}
              placeholder="0"
              className="w-full px-3 py-2 rounded-lg bg-gray-800/50 border border-gray-700 focus:border-synor-500 focus:outline-none text-sm font-mono"
            />
          </div>

          {/* Results */}
          {toAddress && (
            <div className="mt-6 p-4 rounded-lg bg-gray-800/30 border border-gray-700/50">
              <h3 className="font-medium mb-3 flex items-center gap-2">
                <Zap size={16} className="text-amber-400" />
                Estimation Results
              </h3>

              {estimating ? (
                <div className="text-gray-400">Estimating gas...</div>
              ) : estimateError ? (
                <div className="text-red-400 text-sm">
                  {estimateError.message || 'Failed to estimate gas'}
                </div>
              ) : gasEstimate ? (
                <div className="grid sm:grid-cols-2 gap-4">
                  <ResultCard
                    label="Gas Used"
                    value={gasEstimate.gasUsed.toLocaleString()}
                    sublabel="actual gas"
                  />
                  <ResultCard
                    label="Recommended Limit"
                    value={gasEstimate.gasLimitRecommended.toLocaleString()}
                    sublabel="+20% buffer"
                  />
                  <ResultCard
                    label="Estimated Fee"
                    value={gasEstimate.estimatedFee.toLocaleString()}
                    sublabel="sompi"
                  />
                  <ResultCard
                    label="Fee (SYN)"
                    value={gasEstimate.estimatedFeeHuman}
                    sublabel="human readable"
                    highlight
                  />
                </div>
              ) : (
                <div className="text-gray-400">Enter an address to estimate gas</div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Info Box */}
      <div className="bg-synor-500/10 border border-synor-500/30 rounded-xl p-4">
        <h3 className="font-medium text-synor-400 mb-2">About Gas in Synor</h3>
        <ul className="text-sm text-gray-400 space-y-1">
          <li>• Gas measures computational effort required for operations</li>
          <li>• Base fee is 1 sompi per gas unit (subject to network conditions)</li>
          <li>• Dilithium3 signatures use ~5x more gas than Ed25519 due to larger size</li>
          <li>• Contract calls include base cost + execution cost + storage changes</li>
        </ul>
      </div>
    </div>
  );
}

function GasCostRow({
  label,
  value,
  highlight = false,
}: {
  label: string;
  value: number;
  highlight?: boolean;
}) {
  return (
    <div className="flex justify-between items-center text-sm">
      <span className="text-gray-400">{label}</span>
      <span className={`font-mono ${highlight ? 'text-amber-400' : 'text-gray-200'}`}>
        {value.toLocaleString()}
      </span>
    </div>
  );
}

function ResultCard({
  label,
  value,
  sublabel,
  highlight = false,
}: {
  label: string;
  value: string;
  sublabel: string;
  highlight?: boolean;
}) {
  return (
    <div
      className={`p-3 rounded-lg ${
        highlight
          ? 'bg-amber-500/10 border border-amber-500/30'
          : 'bg-gray-800/50 border border-gray-700/50'
      }`}
    >
      <div className="text-xs text-gray-500">{label}</div>
      <div
        className={`text-lg font-bold font-mono ${
          highlight ? 'text-amber-400' : 'text-gray-100'
        }`}
      >
        {value}
      </div>
      <div className="text-xs text-gray-500">{sublabel}</div>
    </div>
  );
}
