﻿import { useEffect, useRef, useState } from 'react';
import { AnchorButton, Callout, Intent, ProgressBar, Spinner, Tab, Tabs, Tag } from '@blueprintjs/core';
import { subscribeToJobStream } from '../../api/provisioningApi';
import { tenantUrl } from '../../config';
import type { ProvisioningProgressEvent } from '../../types/provisioning';

const SAGA_STEPS = [
  'Infrastructure Provisioning',
  'Identity Bootstrapping (Keycloak)',
  'Cryptographic Pre-Flight (Vault)',
  'Database Migration & Seeding (EF Core)',
  'Handoff (Email Magic Link)',
];

type StepStatus = 'pending' | 'running' | 'complete' | 'failed';

interface Props {
  jobId: string;
  subdomain: string;
}

export default function DeploymentLiveStep({ jobId, subdomain }: Props) {
  const [stepStatuses, setStepStatuses] = useState<Record<string, StepStatus>>(
    Object.fromEntries(SAGA_STEPS.map((s) => [s, 'pending' as StepStatus]))
  );
  const [logs, setLogs] = useState<ProvisioningProgressEvent[]>([]);
  const [diagnostics, setDiagnostics] = useState<ProvisioningProgressEvent[]>([]);
  const [finalStatus, setFinalStatus] = useState<'running' | 'complete' | 'failed'>('running');
  const logEndRef  = useRef<HTMLDivElement>(null);
  const diagEndRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let terminal = false;

    const source = subscribeToJobStream(jobId, (evt) => {
      if (evt.type === 'diagnostic') {
        setDiagnostics((prev) => [...prev, evt]);
        return;
      }
      setLogs((prev) => [...prev, evt]);
      if (evt.type === 'step_started' && evt.step)
        setStepStatuses((p) => ({ ...p, [evt.step!]: 'running' }));
      else if (evt.type === 'step_complete' && evt.step)
        setStepStatuses((p) => ({ ...p, [evt.step!]: 'complete' }));
      else if (evt.type === 'step_failed' && evt.step) {
        setStepStatuses((p) => ({ ...p, [evt.step!]: 'failed' }));
        setFinalStatus('failed');
      } else if (evt.type === 'job_complete') {
        terminal = true;
        setFinalStatus('complete');
      } else if (evt.type === 'job_failed') {
        terminal = true;
        setFinalStatus('failed');
      }
    }, () => { if (!terminal) setFinalStatus('failed'); });

    return () => source.close();
  }, [jobId]);

  useEffect(() => { logEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [logs]);
  useEffect(() => { diagEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [diagnostics]);

  const completedCount = Object.values(stepStatuses).filter((s) => s === 'complete').length;
  const clientUrl = tenantUrl(subdomain);

  const progressPanel = (
    <>
      <div className="step-tracker">
        {SAGA_STEPS.map((step) => {
          const status = stepStatuses[step];
          return (
            <div key={step} className="step-tracker-row">
              {status === 'running'  && <Spinner size={14} />}
              {status === 'complete' && <Tag intent={Intent.SUCCESS} minimal round>&#10003;</Tag>}
              {status === 'failed'   && <Tag intent={Intent.DANGER}  minimal round>&#10007;</Tag>}
              {status === 'pending'  && <span className="step-dot" />}
              <span className={`step-label step-${status}`}>{step}</span>
            </div>
          );
        })}
      </div>

      <div className="log-feed">
        {logs.map((log, i) => (
          <div key={i} className={`log-line log-${log.type}`}>
            <span className="log-ts">{new Date(log.timestamp).toLocaleTimeString()}</span>
            <span className="log-msg">{log.message ?? log.type}</span>
          </div>
        ))}
        <div ref={logEndRef} />
      </div>
    </>
  );

  const diagnosticsPanel = (
    <div className="log-feed log-feed--diagnostics">
      {diagnostics.length === 0
        ? <span className="log-msg" style={{ opacity: 0.5 }}>No diagnostics captured.</span>
        : diagnostics.map((d, i) => (
          <div key={i} className="log-line log-diagnostic">
            <span className="log-ts">{new Date(d.timestamp).toLocaleTimeString()}</span>
            <span className="log-step">{d.step}</span>
            <pre className="log-detail">{d.detail ?? d.message}</pre>
          </div>
        ))
      }
      <div ref={diagEndRef} />
    </div>
  );

  return (
    <div className="wizard-step">
      <p className="step-description">
        {finalStatus === 'running'  ? 'Provisioning in progress - do not close this window.' :
         finalStatus === 'complete' ? 'Deployment complete.' : 'Deployment failed. Rollback triggered.'}
      </p>

      <ProgressBar
        value={completedCount / SAGA_STEPS.length}
        intent={finalStatus === 'failed' ? Intent.DANGER : finalStatus === 'complete' ? Intent.SUCCESS : Intent.PRIMARY}
        animate={finalStatus === 'running'}
        stripes={finalStatus === 'running'}
        style={{ marginBottom: '1.5rem' }}
      />

      <Tabs id="deploy-tabs" renderActiveTabPanelOnly={false}>
        <Tab id="progress" title="Progress" panel={progressPanel} />
        <Tab
          id="diagnostics"
          title={
            <span>
              Diagnostics
              {diagnostics.length > 0 && (
                <Tag intent={Intent.DANGER} minimal round style={{ marginLeft: 6 }}>
                  {diagnostics.length}
                </Tag>
              )}
            </span>
          }
          panel={diagnosticsPanel}
        />
      </Tabs>

      {finalStatus === 'complete' && (
        <Callout intent={Intent.SUCCESS} title="Client Provisioned" style={{ marginTop: '1rem' }}>
          <p style={{ marginBottom: '0.75rem' }}>
            Tenant <strong>{subdomain}</strong> is live. The day-zero admin has been set up in Keycloak.
          </p>
          <AnchorButton
            intent={Intent.SUCCESS}
            icon="share"
            text={`Open ${subdomain}.clarity.test`}
            href={clientUrl}
            target="_blank"
            rel="noopener noreferrer"
          />
        </Callout>
      )}
      {finalStatus === 'failed' && (
        <Callout intent={Intent.DANGER} title="Deployment Failed" style={{ marginTop: '1rem' }}>
          A compensating rollback has been triggered. Check the Diagnostics tab for the full stack trace.
        </Callout>
      )}
    </div>
  );
}
