import { useState } from 'react';
import {
  capturePosPayment,
  loadDashboard,
  type CapturePosPaymentRequest,
  type CapturePosPaymentResponse,
  type PosTransactionSummaryResponse
} from './api/dashboardApi';
import { SessionProvider, useSessionContext } from './auth/sessionContext';
import type { IdentityProvider } from './api/sessionApi';

type RouteKey = 'overview' | 'actions';

function App() {
  return (
    <SessionProvider>
      <PosTransactionsShell />
    </SessionProvider>
  );
}

function PosTransactionsShell() {
  const session = useSessionContext();
  const [route, setRoute] = useState<RouteKey>('overview');

  const [contextId, setContextId] = useState('demo-context');
  const [summaryPayload, setSummaryPayload] = useState<PosTransactionSummaryResponse | null>(null);

  const [paymentRequest, setPaymentRequest] = useState<CapturePosPaymentRequest>({
    contextId: 'demo-context',
    transactionId: 'POS-9001',
    amount: 25.5,
    currency: 'USD',
    paymentMethod: 'card'
  });
  const [paymentResponse, setPaymentResponse] = useState<CapturePosPaymentResponse | null>(null);

  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  const loadSummary = async () => {
    setLoading(true);
    setError(null);
    try {
      const payload = await loadDashboard(contextId);
      setSummaryPayload(payload);
      setPaymentRequest((previous) => ({ ...previous, contextId }));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load transaction summary.');
    } finally {
      setLoading(false);
    }
  };

  const capturePayment = async () => {
    setLoading(true);
    setError(null);
    try {
      const payload = await capturePosPayment(paymentRequest);
      setPaymentResponse(payload);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to capture payment.');
    } finally {
      setLoading(false);
    }
  };

  if (session.status === 'loading') {
    return (
      <main className="app">
        <h1>POS Transactions Web</h1>
        <p className="muted">Restoring session...</p>
      </main>
    );
  }

  if (session.status !== 'authenticated' || !session.profile) {
    return (
      <main className="app">
        <h1>POS Transactions Web</h1>
        <p className="muted">Sign in with Thalos to access protected routes.</p>
        {session.error && <div className="alert">{session.error}</div>}
        <LoginCard />
      </main>
    );
  }

  return (
    <main className="app">
      <h1>POS Transactions Web</h1>
      <p className="muted">Transaction summary and payment capture MVP workflows.</p>

      <section className="card row">
        <span className="badge">subject: {session.profile.subjectId}</span>
        <span className="badge">tenant: {session.profile.tenantId}</span>
        <span className="badge">provider: {providerLabel(session.profile.provider)}</span>
        <span className="spacer" />
        <button type="button" className="secondary" onClick={() => void session.refresh()}>
          Refresh Session
        </button>
        <button type="button" className="warn" onClick={() => void session.logout()}>
          Logout
        </button>
      </section>

      <section className="card tabs" aria-label="route-shell">
        <button
          type="button"
          className={route === 'overview' ? 'active' : undefined}
          onClick={() => setRoute('overview')}
        >
          Summary
        </button>
        <button
          type="button"
          className={route === 'actions' ? 'active' : undefined}
          onClick={() => setRoute('actions')}
        >
          Capture Payment
        </button>
      </section>

      {session.error && <div className="alert">{session.error}</div>}
      {error && <div className="alert">{error}</div>}

      {route === 'overview' && (
        <section className="card col">
          <div className="row">
            <label className="col">
              Context Id
              <input value={contextId} onChange={(event) => setContextId(event.target.value)} />
            </label>
            <button type="button" onClick={() => void loadSummary()} disabled={loading}>
              {loading ? 'Loading...' : 'Load Summary'}
            </button>
          </div>
          <pre>{JSON.stringify(summaryPayload, null, 2)}</pre>
        </section>
      )}

      {route === 'actions' && (
        <section className="card col">
          <div className="grid">
            <label className="col">
              Context Id
              <input
                value={paymentRequest.contextId}
                onChange={(event) => setPaymentRequest((previous) => ({ ...previous, contextId: event.target.value }))}
              />
            </label>
            <label className="col">
              Transaction Id
              <input
                value={paymentRequest.transactionId}
                onChange={(event) => setPaymentRequest((previous) => ({ ...previous, transactionId: event.target.value }))}
              />
            </label>
            <label className="col">
              Amount
              <input
                type="number"
                min={0}
                step="0.01"
                value={paymentRequest.amount}
                onChange={(event) =>
                  setPaymentRequest((previous) => ({
                    ...previous,
                    amount: Math.max(0, Number(event.target.value) || 0)
                  }))
                }
              />
            </label>
            <label className="col">
              Currency
              <input
                value={paymentRequest.currency}
                onChange={(event) => setPaymentRequest((previous) => ({ ...previous, currency: event.target.value.toUpperCase() }))}
              />
            </label>
            <label className="col">
              Payment Method
              <input
                value={paymentRequest.paymentMethod}
                onChange={(event) => setPaymentRequest((previous) => ({ ...previous, paymentMethod: event.target.value }))}
              />
            </label>
          </div>
          <button type="button" onClick={() => void capturePayment()} disabled={loading}>
            {loading ? 'Capturing...' : 'Capture Payment Now'}
          </button>
          <pre>{JSON.stringify(paymentResponse, null, 2)}</pre>
        </section>
      )}
    </main>
  );
}

function LoginCard() {
  const session = useSessionContext();
  const [subjectId, setSubjectId] = useState('demo-user');
  const [tenantId, setTenantId] = useState('demo-tenant');
  const [provider, setProvider] = useState<IdentityProvider>(0);
  const [externalToken, setExternalToken] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const onSubmit = async () => {
    setSubmitting(true);
    setError(null);
    try {
      await session.login({ subjectId, tenantId, provider, externalToken });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Login failed.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <section className="card col">
      <div className="grid">
        <label className="col">
          Subject Id
          <input value={subjectId} onChange={(event) => setSubjectId(event.target.value)} />
        </label>
        <label className="col">
          Tenant Id
          <input value={tenantId} onChange={(event) => setTenantId(event.target.value)} />
        </label>
        <label className="col">
          Provider
          <select value={String(provider)} onChange={(event) => setProvider(Number(event.target.value) as IdentityProvider)}>
            <option value="0">Internal JWT</option>
            <option value="1">Azure AD (simulated)</option>
            <option value="2">Google (simulated)</option>
          </select>
        </label>
      </div>
      <label className="col">
        External Token (optional)
        <input value={externalToken} onChange={(event) => setExternalToken(event.target.value)} />
      </label>
      <button type="button" onClick={() => void onSubmit()} disabled={submitting}>
        {submitting ? 'Signing In...' : 'Sign In'}
      </button>
      {error && <div className="alert">{error}</div>}
    </section>
  );
}

function providerLabel(provider: IdentityProvider): string {
  if (provider === 0 || provider === '0' || provider === 'InternalJwt') {
    return 'Internal JWT';
  }

  if (provider === 1 || provider === '1' || provider === 'AzureAd') {
    return 'Azure AD';
  }

  if (provider === 2 || provider === '2' || provider === 'Google') {
    return 'Google';
  }

  return String(provider);
}

export default App;
