import { useState, useRef } from 'react';
import {
  Alert, AlertDialog, Badge, Button, Card, DataTable,
  EmptyState, FileInput, FormField, Input, Spinner, useToast,
} from '@cameleer/design-system';
import type { Column, FileInputHandle } from '@cameleer/design-system';
import { Shield, Plus, Trash2, FlaskConical, Upload, ShieldCheck } from 'lucide-react';
import {
  useSsoConnectors, useCreateSsoConnector, useDeleteSsoConnector, useTestSsoConnector,
} from '../../api/tenant-hooks';
import {
  useTenantCaCerts, useStageCaCert, useActivateCaCert, useDeleteCaCert,
} from '../../api/ca-hooks';
import type { CaCertResponse } from '../../api/ca-hooks';
import type { SsoConnector } from '../../types/api';
import styles from '../../styles/platform.module.css';

const PROVIDERS = [
  { value: 'OIDC', label: 'OIDC', type: 'oidc' },
  { value: 'SAML', label: 'SAML', type: 'saml' },
  { value: 'AzureAD', label: 'Azure AD (SAML)', type: 'saml' },
  { value: 'AzureAdOidc', label: 'Azure AD (OIDC)', type: 'oidc' },
  { value: 'GoogleWorkspace', label: 'Google Workspace', type: 'oidc' },
  { value: 'Okta', label: 'Okta', type: 'oidc' },
];

function providerType(name: string): 'oidc' | 'saml' {
  return PROVIDERS.find((p) => p.value === name)?.type as 'oidc' | 'saml' ?? 'oidc';
}

function providerLabel(name: string): string {
  return PROVIDERS.find((p) => p.value === name)?.label ?? name;
}

const selectStyle: React.CSSProperties = {
  width: '100%', padding: '6px 10px', borderRadius: 6,
  border: '1px solid var(--border)', background: 'var(--bg-surface)',
  color: 'var(--text-primary)', fontSize: '0.875rem',
};

export function SsoPage() {
  const { data: connectors, isLoading, isError } = useSsoConnectors();
  const createConnector = useCreateSsoConnector();
  const deleteConnector = useDeleteSsoConnector();
  const testConnector = useTestSsoConnector();
  const { toast } = useToast();

  const [showCreate, setShowCreate] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<SsoConnector | null>(null);

  // Create form state
  const [provider, setProvider] = useState('OIDC');
  const [connectorName, setConnectorName] = useState('');
  const [domains, setDomains] = useState('');
  // OIDC fields
  const [issuer, setIssuer] = useState('');
  const [clientId, setClientId] = useState('');
  const [clientSecret, setClientSecret] = useState('');
  // SAML fields
  const [metadataUrl, setMetadataUrl] = useState('');

  function resetForm() {
    setProvider('OIDC');
    setConnectorName('');
    setDomains('');
    setIssuer('');
    setClientId('');
    setClientSecret('');
    setMetadataUrl('');
    setShowCreate(false);
  }

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    const type = providerType(provider);
    const config: Record<string, unknown> = type === 'oidc'
      ? { clientId, clientSecret, issuer: issuer || undefined }
      : { metadataUrl };

    try {
      await createConnector.mutateAsync({
        providerName: provider,
        connectorName,
        config,
        domains: domains.split(',').map((d) => d.trim()).filter(Boolean),
      });
      toast({ title: `SSO connector "${connectorName}" created`, variant: 'success' });
      resetForm();
    } catch (err) {
      toast({ title: 'Failed to create connector', description: String(err), variant: 'error' });
    }
  }

  async function handleDelete() {
    if (!deleteTarget) return;
    try {
      await deleteConnector.mutateAsync(deleteTarget.id);
      toast({ title: `Deleted "${deleteTarget.connectorName}"`, variant: 'success' });
      setDeleteTarget(null);
    } catch (err) {
      toast({ title: 'Delete failed', description: String(err), variant: 'error' });
      setDeleteTarget(null);
    }
  }

  async function handleTest(connector: SsoConnector) {
    try {
      const result = await testConnector.mutateAsync(connector.id);
      if (result.status === 'ok') {
        toast({ title: 'Connection test passed', description: `${connector.connectorName} is reachable`, variant: 'success' });
      } else {
        toast({ title: 'Connection test failed', description: 'IdP metadata could not be resolved', variant: 'warning' });
      }
    } catch (err) {
      toast({ title: 'Connection test failed', description: String(err), variant: 'error' });
    }
  }

  const columns: Column<SsoConnector>[] = [
    {
      key: 'connectorName',
      header: 'Name',
      render: (_v, row) => row.connectorName,
    },
    {
      key: 'providerName',
      header: 'Provider',
      render: (_v, row) => <Badge label={providerLabel(row.providerName)} color="primary" />,
    },
    {
      key: 'domains',
      header: 'Domains',
      render: (_v, row) => (
        <span style={{ fontFamily: 'monospace', fontSize: '0.8125rem' }}>
          {row.domains?.join(', ') || '--'}
        </span>
      ),
    },
    {
      key: 'id',
      header: 'Actions',
      render: (_v, row) => (
        <div style={{ display: 'flex', gap: 4 }}>
          <Button
            variant="secondary"
            onClick={(e) => { e.stopPropagation(); handleTest(row); }}
            disabled={testConnector.isPending}
          >
            <FlaskConical size={14} style={{ marginRight: 4 }} />
            Test
          </Button>
          <Button
            variant="danger"
            onClick={(e) => { e.stopPropagation(); setDeleteTarget(row); }}
          >
            <Trash2 size={14} />
          </Button>
        </div>
      ),
    },
  ];

  if (isLoading) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 64 }}>
        <Spinner />
      </div>
    );
  }

  if (isError) {
    return (
      <div style={{ padding: 24 }}>
        <Alert variant="error" title="Failed to load SSO connectors">
          Could not fetch SSO configuration. Please refresh.
        </Alert>
      </div>
    );
  }

  const isOidc = providerType(provider) === 'oidc';

  return (
    <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <h1 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600 }}>Enterprise SSO</h1>
        <Button variant="primary" onClick={() => setShowCreate((v) => !v)}>
          <Plus size={16} style={{ marginRight: 6, verticalAlign: -3 }} />
          Add SSO Connection
        </Button>
      </div>

      {showCreate && (
        <Card title="New SSO Connection">
          <form onSubmit={handleCreate} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <FormField label="Provider" htmlFor="sso-provider">
              <select id="sso-provider" value={provider} onChange={(e) => setProvider(e.target.value)} style={selectStyle}>
                {PROVIDERS.map((p) => (
                  <option key={p.value} value={p.value}>{p.label}</option>
                ))}
              </select>
            </FormField>

            <FormField label="Display Name" htmlFor="sso-name">
              <Input
                id="sso-name"
                placeholder="e.g. Acme Corp SSO"
                value={connectorName}
                onChange={(e) => setConnectorName(e.target.value)}
                required
              />
            </FormField>

            <FormField label="Email Domains" htmlFor="sso-domains" hint="Comma-separated domains for SSO routing (e.g. acme.com)">
              <Input
                id="sso-domains"
                placeholder="acme.com, acme.io"
                value={domains}
                onChange={(e) => setDomains(e.target.value)}
              />
            </FormField>

            {isOidc ? (
              <>
                {provider !== 'GoogleWorkspace' && (
                  <FormField label="Issuer URI" htmlFor="sso-issuer">
                    <Input
                      id="sso-issuer"
                      type="url"
                      placeholder="https://login.microsoftonline.com/{tenant}/v2.0"
                      value={issuer}
                      onChange={(e) => setIssuer(e.target.value)}
                      required
                    />
                  </FormField>
                )}
                <FormField label="Client ID" htmlFor="sso-client-id">
                  <Input
                    id="sso-client-id"
                    value={clientId}
                    onChange={(e) => setClientId(e.target.value)}
                    required
                  />
                </FormField>
                <FormField label="Client Secret" htmlFor="sso-client-secret">
                  <Input
                    id="sso-client-secret"
                    type="password"
                    value={clientSecret}
                    onChange={(e) => setClientSecret(e.target.value)}
                    required
                  />
                </FormField>
              </>
            ) : (
              <FormField label="SAML Metadata URL" htmlFor="sso-metadata">
                <Input
                  id="sso-metadata"
                  type="url"
                  placeholder="https://idp.acme.com/metadata.xml"
                  value={metadataUrl}
                  onChange={(e) => setMetadataUrl(e.target.value)}
                  required
                />
              </FormField>
            )}

            <div style={{ display: 'flex', gap: 8 }}>
              <Button type="submit" variant="primary" loading={createConnector.isPending}>
                Create
              </Button>
              <Button type="button" variant="secondary" onClick={resetForm}>
                Cancel
              </Button>
            </div>
          </form>
        </Card>
      )}

      {(!connectors || connectors.length === 0) && !showCreate && (
        <EmptyState
          icon={<Shield size={32} />}
          title="No SSO connections"
          description="Add an enterprise SSO connection to let your team sign in with their corporate identity provider."
          action={
            <Button variant="primary" onClick={() => setShowCreate(true)}>
              <Plus size={16} style={{ marginRight: 6, verticalAlign: -3 }} />
              Add SSO Connection
            </Button>
          }
        />
      )}

      {connectors && connectors.length > 0 && (
        <DataTable columns={columns} data={connectors} />
      )}

      <AlertDialog
        open={deleteTarget !== null}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        title="Delete SSO Connection"
        description={`Are you sure you want to delete "${deleteTarget?.connectorName ?? ''}"? Users authenticating via this provider will lose access.`}
        confirmLabel="Delete"
        cancelLabel="Cancel"
        variant="danger"
        loading={deleteConnector.isPending}
      />

      <CaCertificatesSection />
    </div>
  );
}

// --- CA Certificates Section ---

function formatDate(iso: string | null | undefined): string {
  if (!iso) return '—';
  return new Date(iso).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
}

function shortenFingerprint(fp: string | null | undefined): string {
  if (!fp) return '—';
  return fp.length > 23 ? fp.slice(0, 23) + '...' : fp;
}

function CaCertificatesSection() {
  const { data: certs, isLoading } = useTenantCaCerts();
  const stageMutation = useStageCaCert();
  const activateMutation = useActivateCaCert();
  const deleteMutation = useDeleteCaCert();
  const { toast } = useToast();

  const certRef = useRef<FileInputHandle>(null);
  const [label, setLabel] = useState('');
  const [deleteTarget, setDeleteTarget] = useState<CaCertResponse | null>(null);

  async function handleUpload() {
    const file = certRef.current?.file;
    if (!file) {
      toast({ title: 'Select a CA certificate file', variant: 'error' });
      return;
    }
    const formData = new FormData();
    formData.append('cert', file);
    if (label.trim()) formData.append('label', label.trim());

    try {
      await stageMutation.mutateAsync(formData);
      toast({ title: 'CA certificate staged', variant: 'success' });
      certRef.current?.clear();
      setLabel('');
    } catch (err) {
      toast({ title: 'Upload failed', description: String(err), variant: 'error' });
    }
  }

  async function handleActivate(id: string) {
    try {
      await activateMutation.mutateAsync(id);
      toast({ title: 'CA certificate activated', variant: 'success' });
    } catch (err) {
      toast({ title: 'Activation failed', description: String(err), variant: 'error' });
    }
  }

  async function handleDelete() {
    if (!deleteTarget) return;
    try {
      await deleteMutation.mutateAsync(deleteTarget.id);
      toast({ title: 'CA certificate removed', variant: 'success' });
      setDeleteTarget(null);
    } catch (err) {
      toast({ title: 'Delete failed', description: String(err), variant: 'error' });
      setDeleteTarget(null);
    }
  }

  const active = certs?.filter((c) => c.status === 'ACTIVE') ?? [];
  const staged = certs?.filter((c) => c.status === 'STAGED') ?? [];

  return (
    <>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 12 }}>
        <h2 style={{ margin: 0, fontSize: '1.1rem', fontWeight: 600 }}>CA Certificates</h2>
      </div>

      <p style={{ fontSize: '0.875rem', color: 'var(--text-secondary)', margin: 0 }}>
        Upload CA certificates if your identity provider uses a private or internal certificate authority.
        Certificates are staged first, then activated to take effect.
      </p>

      {isLoading ? (
        <div style={{ display: 'flex', justifyContent: 'center', padding: 32 }}>
          <Spinner />
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))', gap: 16 }}>
          {/* Upload card */}
          <Card title="Upload CA Certificate">
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <div>
                <label style={{ fontSize: 13, color: 'var(--text-secondary)', display: 'block', marginBottom: 4 }}>
                  Label (optional)
                </label>
                <Input
                  placeholder="e.g. Acme Corp Root CA"
                  value={label}
                  onChange={(e) => setLabel(e.target.value)}
                />
              </div>
              <FormField label="CA Certificate (PEM) *">
                <FileInput ref={certRef} accept=".pem,.crt,.cer" icon={<ShieldCheck size={16} />} />
              </FormField>
              <Button variant="primary" onClick={handleUpload} loading={stageMutation.isPending}>
                <Upload size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                Stage Certificate
              </Button>
            </div>
          </Card>

          {/* Staged certs */}
          {staged.map((cert) => (
            <Card key={cert.id} title={cert.label || 'Staged CA'}>
              <div className={styles.dividerList}>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Status</span>
                  <Badge label="Staged" color="warning" />
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Subject</span>
                  <span className={styles.kvValue}>{cert.subject}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Issuer</span>
                  <span className={styles.kvValue}>{cert.issuer}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Expires</span>
                  <span className={styles.kvValue}>{formatDate(cert.notAfter)}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Fingerprint</span>
                  <span className={styles.kvValueMono} title={cert.fingerprint} style={{ fontSize: '0.7rem' }}>
                    {shortenFingerprint(cert.fingerprint)}
                  </span>
                </div>
                <div style={{ paddingTop: 8, display: 'flex', gap: 8 }}>
                  <Button variant="primary" onClick={() => handleActivate(cert.id)} loading={activateMutation.isPending}>
                    <ShieldCheck size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                    Activate
                  </Button>
                  <Button variant="danger" onClick={() => setDeleteTarget(cert)}>
                    <Trash2 size={14} />
                  </Button>
                </div>
              </div>
            </Card>
          ))}

          {/* Active certs */}
          {active.map((cert) => (
            <Card key={cert.id} title={cert.label || 'Active CA'}>
              <div className={styles.dividerList}>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Status</span>
                  <Badge label="Active" color="success" />
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Subject</span>
                  <span className={styles.kvValue}>{cert.subject}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Issuer</span>
                  <span className={styles.kvValue}>{cert.issuer}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Expires</span>
                  <span className={styles.kvValue}>{formatDate(cert.notAfter)}</span>
                </div>
                <div className={styles.kvRow}>
                  <span className={styles.kvLabel}>Fingerprint</span>
                  <span className={styles.kvValueMono} title={cert.fingerprint} style={{ fontSize: '0.7rem' }}>
                    {shortenFingerprint(cert.fingerprint)}
                  </span>
                </div>
                <div style={{ paddingTop: 8 }}>
                  <Button variant="danger" onClick={() => setDeleteTarget(cert)}>
                    <Trash2 size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                    Remove
                  </Button>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}

      <AlertDialog
        open={deleteTarget !== null}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        title="Remove CA Certificate"
        description={`Remove "${deleteTarget?.label || deleteTarget?.subject || ''}"? Services using this CA for trust may lose connectivity.`}
        confirmLabel="Remove"
        cancelLabel="Cancel"
        variant="danger"
        loading={deleteMutation.isPending}
      />
    </>
  );
}
