import { LitElement, html, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { generatePolicy, generatePolicyFromAudit } from '../api';
import '@shoelace-style/shoelace/dist/components/dialog/dialog.js';
import '@shoelace-style/shoelace/dist/components/textarea/textarea.js';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/switch/switch.js';
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
import '@shoelace-style/shoelace/dist/components/spinner/spinner.js';
import '@shoelace-style/shoelace/dist/components/tab-group/tab-group.js';
import '@shoelace-style/shoelace/dist/components/tab/tab.js';
import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js';
import '@shoelace-style/shoelace/dist/components/input/input.js';
import '@shoelace-style/shoelace/dist/components/copy-button/copy-button.js';

@customElement('policy-generate-dialog')
export class PolicyGenerateDialog extends LitElement {
  @property({ type: Boolean }) open = false;

  @state() private _prompt = '';
  @state() private _includeContext = true;
  @state() private _loading = false;
  @state() private _error = '';
  @state() private _generatedYaml = '';
  @state() private _warnings: string[] = [];
  @state() private _activeTab = 'prompt';
  @state() private _startDate = '';
  @state() private _endDate = '';

  static styles = css`
    :host {
      --dialog-width: 720px;
    }

    sl-dialog::part(panel) {
      max-width: var(--dialog-width);
      width: 90vw;
    }

    sl-dialog::part(body) {
      padding: 1rem 1.5rem;
    }

    .description {
      color: var(--sl-color-neutral-600);
      font-size: 0.875rem;
      margin-bottom: 1rem;
      line-height: 1.5;
    }

    .form-group {
      margin-bottom: 1rem;
    }

    .form-row {
      display: flex;
      gap: 1rem;
    }

    .form-row > * {
      flex: 1;
    }

    .options-row {
      display: flex;
      align-items: center;
      gap: 1rem;
      margin-top: 0.75rem;
    }

    .options-row sl-switch {
      font-size: 0.875rem;
    }

    .yaml-preview {
      background: var(--sl-color-neutral-50);
      border: 1px solid var(--sl-color-neutral-200);
      border-radius: var(--sl-border-radius-medium);
      padding: 1rem;
      margin-top: 1rem;
      position: relative;
      max-height: 400px;
      overflow: auto;
    }

    .yaml-preview pre {
      margin: 0;
      font-family: var(--sl-font-mono);
      font-size: 0.8125rem;
      line-height: 1.6;
      white-space: pre-wrap;
      word-break: break-word;
    }

    .yaml-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 1rem;
      margin-bottom: 0.5rem;
    }

    .yaml-header h4 {
      margin: 0;
      font-size: 0.875rem;
      color: var(--sl-color-neutral-700);
    }

    .yaml-actions {
      display: flex;
      gap: 0.5rem;
    }

    .loading-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 2rem;
      gap: 1rem;
      color: var(--sl-color-neutral-600);
    }

    .loading-container sl-spinner {
      font-size: 2rem;
      --track-width: 3px;
    }

    .warning-list {
      margin-top: 0.5rem;
    }

    .footer-actions {
      display: flex;
      gap: 0.75rem;
      justify-content: flex-end;
    }
  `;

  render() {
    return html`
      <sl-dialog
        label="Generate Policy with AI"
        ?open=${this.open}
        @sl-request-close=${this._handleClose}
        @sl-after-hide=${this._handleClose}
      >
        <p class="description">
          Describe the policy you want, or generate one from your audit logs. An
          AI model configured on your account will generate valid policy YAML.
        </p>

        <sl-tab-group @sl-tab-show=${this._handleTabChange}>
          <sl-tab
            slot="nav"
            panel="prompt"
            ?active=${this._activeTab === 'prompt'}
          >
            From Description
          </sl-tab>
          <sl-tab
            slot="nav"
            panel="audit"
            ?active=${this._activeTab === 'audit'}
          >
            From Audit Logs
          </sl-tab>

          <sl-tab-panel name="prompt">
            <div class="form-group">
              <sl-textarea
                label="Describe your policy"
                placeholder="e.g. Require approval for any payment over $500. Deny all file deletion tools. Allow read-only tools without approval."
                rows="5"
                .value=${this._prompt}
                @sl-input=${(e: Event) =>
                  (this._prompt = (e.target as HTMLTextAreaElement).value)}
                ?disabled=${this._loading}
              ></sl-textarea>
            </div>
            <div class="options-row">
              <sl-switch
                ?checked=${this._includeContext}
                @sl-change=${(e: Event) =>
                  (this._includeContext = (e.target as any).checked)}
                ?disabled=${this._loading}
              >
                Include current config as context
              </sl-switch>
            </div>
          </sl-tab-panel>

          <sl-tab-panel name="audit">
            <p class="description">
              Analyse your historical tool-call patterns and generate a policy
              that allows normal usage and flags outliers.
            </p>
            <div class="form-row">
              <sl-input
                label="Start date (optional)"
                type="date"
                .value=${this._startDate}
                @sl-input=${(e: Event) =>
                  (this._startDate = (e.target as HTMLInputElement).value)}
                ?disabled=${this._loading}
              ></sl-input>
              <sl-input
                label="End date (optional)"
                type="date"
                .value=${this._endDate}
                @sl-input=${(e: Event) =>
                  (this._endDate = (e.target as HTMLInputElement).value)}
                ?disabled=${this._loading}
              ></sl-input>
            </div>
          </sl-tab-panel>
        </sl-tab-group>

        ${this._loading
          ? html`
              <div class="loading-container">
                <sl-spinner></sl-spinner>
                <span>Generating policy…</span>
              </div>
            `
          : ''}
        ${this._error
          ? html`
              <sl-alert variant="danger" open>
                <sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
                ${this._error}
              </sl-alert>
            `
          : ''}
        ${this._warnings.length > 0
          ? html`
              <div class="warning-list">
                ${this._warnings.map(
                  (w) => html`
                    <sl-alert variant="warning" open>
                      <sl-icon
                        slot="icon"
                        name="exclamation-triangle"
                      ></sl-icon>
                      ${w}
                    </sl-alert>
                  `
                )}
              </div>
            `
          : ''}
        ${this._generatedYaml
          ? html`
              <div class="yaml-header">
                <h4>Generated Policy</h4>
                <div class="yaml-actions">
                  <sl-copy-button
                    .value=${this._generatedYaml}
                  ></sl-copy-button>
                  <sl-button size="small" @click=${this._downloadYaml}>
                    <sl-icon slot="prefix" name="download"></sl-icon>
                    Download
                  </sl-button>
                </div>
              </div>
              <div class="yaml-preview">
                <pre>${this._generatedYaml}</pre>
              </div>
            `
          : ''}

        <div slot="footer" class="footer-actions">
          <sl-button variant="default" @click=${this._handleClose}
            >Cancel</sl-button
          >
          ${this._generatedYaml
            ? html`
                <sl-button
                  variant="primary"
                  @click=${this._applyPolicy}
                  ?loading=${this._loading}
                >
                  <sl-icon slot="prefix" name="check-lg"></sl-icon>
                  Apply Policy
                </sl-button>
              `
            : html`
                <sl-button
                  variant="primary"
                  @click=${this._generate}
                  ?loading=${this._loading}
                  ?disabled=${this._activeTab === 'prompt' &&
                  !this._prompt.trim()}
                >
                  <sl-icon slot="prefix" name="magic"></sl-icon>
                  Generate
                </sl-button>
              `}
        </div>
      </sl-dialog>
    `;
  }

  private _handleTabChange(e: CustomEvent) {
    this._activeTab = e.detail.name;
  }

  private async _generate() {
    this._loading = true;
    this._error = '';
    this._generatedYaml = '';
    this._warnings = [];

    try {
      let result;
      if (this._activeTab === 'audit') {
        result = await generatePolicyFromAudit({
          startDate: this._startDate || undefined,
          endDate: this._endDate || undefined,
        });
      } else {
        result = await generatePolicy({
          prompt: this._prompt,
          includeCurrentConfig: this._includeContext,
        });
      }

      this._generatedYaml = result.yaml;
      this._warnings = result.warnings || [];
    } catch (err: any) {
      this._error = err.message || 'Generation failed';
    } finally {
      this._loading = false;
    }
  }

  private _downloadYaml() {
    const blob = new Blob([this._generatedYaml], {
      type: 'application/x-yaml',
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'generated-policy.yaml';
    a.click();
    URL.revokeObjectURL(url);
  }

  private _applyPolicy() {
    this.dispatchEvent(
      new CustomEvent('policy-apply', {
        detail: { yaml: this._generatedYaml },
        bubbles: true,
        composed: true,
      })
    );
  }

  private _handleClose() {
    this.open = false;
    this._prompt = '';
    this._generatedYaml = '';
    this._error = '';
    this._warnings = [];
    this._loading = false;
    this.dispatchEvent(new CustomEvent('closed'));
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'policy-generate-dialog': PolicyGenerateDialog;
  }
}
