import * as plugins from '../../plugins.js';
import {
  DeesElement,
  property,
  html,
  customElement,
  type TemplateResult,
  css,
  cssManager,
  unsafeCSS,
  state,
} from '@design.estate/dees-element';
import * as sharedStyles from '../../styles/shared.styles.js';
import type { IMonitorFormData, IServiceStatus } from '../../interfaces/index.js';
import { demoFunc } from './upladmin-monitor-form.demo.js';

declare global {
  interface HTMLElementTagNameMap {
    'upladmin-monitor-form': UpladminMonitorForm;
  }
}

type TStatusType = 'operational' | 'degraded' | 'partial_outage' | 'major_outage' | 'maintenance';

@customElement('upladmin-monitor-form')
export class UpladminMonitorForm extends DeesElement {
  public static demo = demoFunc;

  @property({ type: Object })
  accessor monitor: IMonitorFormData | null = null;

  @property({ type: Array })
  accessor availableMonitors: IServiceStatus[] = [];

  @property({ type: Array })
  accessor categories: string[] = [];

  @property({ type: Boolean })
  accessor loading: boolean = false;

  @state()
  accessor formData: IMonitorFormData = {
    name: '',
    displayName: '',
    description: '',
    category: '',
    dependencies: [],
    currentStatus: 'operational',
  };

  @state()
  accessor errors: Record<string, string> = {};

  private statusIcons: Record<TStatusType, string> = {
    operational: 'lucide:CheckCircle',
    degraded: 'lucide:AlertTriangle',
    partial_outage: 'lucide:AlertOctagon',
    major_outage: 'lucide:XCircle',
    maintenance: 'lucide:Wrench',
  };

  public static styles = [
    plugins.domtools.elementBasic.staticStyles,
    sharedStyles.commonStyles,
    css`
      :host {
        display: block;
        font-family: ${unsafeCSS(sharedStyles.fonts.base)};
      }

      .form-container {
        background: ${sharedStyles.colors.background.secondary};
        border: 1px solid ${sharedStyles.colors.border.default};
        border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
        overflow: hidden;
      }

      .form-header {
        display: flex;
        align-items: center;
        gap: ${unsafeCSS(sharedStyles.spacing.md)};
        padding: ${unsafeCSS(sharedStyles.spacing.lg)};
        border-bottom: 1px solid ${sharedStyles.colors.border.default};
        background: ${sharedStyles.colors.background.muted};
      }

      .form-header dees-icon {
        --icon-color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
      }

      .form-title-wrapper {
        flex: 1;
      }

      .form-title {
        font-size: 18px;
        font-weight: 600;
        color: ${sharedStyles.colors.text.primary};
        margin: 0;
      }

      .form-subtitle {
        font-size: 13px;
        color: ${sharedStyles.colors.text.muted};
        margin-top: 4px;
      }

      .form-body {
        display: grid;
        gap: ${unsafeCSS(sharedStyles.spacing.lg)};
        padding: ${unsafeCSS(sharedStyles.spacing.lg)};
      }

      dees-form {
        display: contents;
      }

      .form-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: ${unsafeCSS(sharedStyles.spacing.md)};
      }

      @media (max-width: 600px) {
        .form-row {
          grid-template-columns: 1fr;
        }
      }

      .form-actions {
        display: flex;
        justify-content: flex-end;
        gap: ${unsafeCSS(sharedStyles.spacing.sm)};
        padding: ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.lg)};
        border-top: 1px solid ${sharedStyles.colors.border.default};
        background: ${sharedStyles.colors.background.muted};
      }

      .status-section {
        margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
      }

      .status-options {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
        gap: ${unsafeCSS(sharedStyles.spacing.sm)};
      }

      .status-option {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 14px 16px;
        background: ${sharedStyles.colors.background.primary};
        border: 2px solid ${sharedStyles.colors.border.default};
        border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
        cursor: pointer;
        transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
      }

      .status-option:hover {
        border-color: ${sharedStyles.colors.border.strong};
        background: ${sharedStyles.colors.background.muted};
      }

      .status-option.selected {
        border-color: ${sharedStyles.colors.accent.primary};
        background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.05)', 'rgba(96, 165, 250, 0.1)')};
      }

      .status-option input {
        display: none;
      }

      .status-option dees-icon {
        flex-shrink: 0;
      }

      .status-option.operational dees-icon { --icon-color: ${sharedStyles.colors.status.operational}; }
      .status-option.degraded dees-icon { --icon-color: ${sharedStyles.colors.status.degraded}; }
      .status-option.partial_outage dees-icon { --icon-color: ${sharedStyles.colors.status.partialOutage}; }
      .status-option.major_outage dees-icon { --icon-color: ${sharedStyles.colors.status.majorOutage}; }
      .status-option.maintenance dees-icon { --icon-color: ${sharedStyles.colors.status.maintenance}; }

      .status-label {
        font-size: 14px;
        font-weight: 500;
        color: ${sharedStyles.colors.text.primary};
      }

      .field-label {
        display: block;
        font-size: 13px;
        font-weight: 500;
        color: ${sharedStyles.colors.text.primary};
        margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
      }

      .field-label.required::after {
        content: ' *';
        color: ${sharedStyles.colors.accent.danger};
      }

      /* Style dees-input components */
      dees-input-text,
      dees-input-dropdown {
        --dees-input-background: ${sharedStyles.colors.background.primary};
        --dees-input-border-color: ${sharedStyles.colors.border.default};
      }
    `
  ];

  async connectedCallback() {
    await super.connectedCallback();
    if (this.monitor) {
      this.formData = { ...this.monitor };
    }
  }

  updated(changedProperties: Map<string, unknown>) {
    if (changedProperties.has('monitor') && this.monitor) {
      this.formData = { ...this.monitor };
    }
  }

  public render(): TemplateResult {
    const isEdit = !!this.monitor?.id;
    const statusOptions: Array<{ value: TStatusType; label: string }> = [
      { value: 'operational', label: 'Operational' },
      { value: 'degraded', label: 'Degraded' },
      { value: 'partial_outage', label: 'Partial Outage' },
      { value: 'major_outage', label: 'Major Outage' },
      { value: 'maintenance', label: 'Maintenance' },
    ];

    const categoryOptions = this.categories.map(cat => ({ key: cat, option: cat, payload: null }));
    const dependencyOptions = this.availableMonitors
      .filter(m => m.id !== this.monitor?.id)
      .map(m => ({ key: m.id, option: m.displayName || m.name, payload: null }));

    return html`
      <div class="form-container">
        <div class="form-header">
          <dees-icon .icon=${isEdit ? 'lucide:Pencil' : 'lucide:Plus'} .iconSize=${24}></dees-icon>
          <div class="form-title-wrapper">
            <h2 class="form-title">${isEdit ? 'Edit Monitor' : 'Create Monitor'}</h2>
            <p class="form-subtitle">
              ${isEdit ? 'Update the monitor configuration' : 'Add a new service to monitor'}
            </p>
          </div>
        </div>

        <div class="form-body">
          <dees-form>
            <div class="form-row">
              <dees-input-text
                key="name"
                label="Internal Name"
                .value="${this.formData.name}"
                placeholder="api-server"
                required
                description="Lowercase, no spaces. Used as identifier."
                @changeSubject="${this.handleNameChange}"
              ></dees-input-text>

              <dees-input-text
                key="displayName"
                label="Display Name"
                .value="${this.formData.displayName}"
                placeholder="API Server"
                required
                description="Human-readable name shown to users."
                @changeSubject="${this.handleDisplayNameChange}"
              ></dees-input-text>
            </div>

            <dees-input-text
              key="description"
              label="Description"
              inputType="textarea"
              .value="${this.formData.description || ''}"
              placeholder="Brief description of what this service does..."
              @changeSubject="${this.handleDescriptionChange}"
            ></dees-input-text>

            <div class="form-row">
              <dees-input-dropdown
                key="category"
                label="Category"
                .options="${categoryOptions}"
                .selectedOption="${this.formData.category || ''}"
                placeholder="Select category..."
                @selectedOption="${this.handleCategoryChange}"
              ></dees-input-dropdown>

              <dees-input-dropdown
                key="dependencies"
                label="Dependencies"
                .options="${dependencyOptions}"
                .selectedOptions="${this.formData.dependencies || []}"
                multiple
                description="Services this monitor depends on."
                @selectedOption="${this.handleDependenciesChange}"
              ></dees-input-dropdown>
            </div>

            <div class="status-section">
              <label class="field-label required">Current Status</label>
              <div class="status-options">
                ${statusOptions.map(opt => html`
                  <label
                    class="status-option ${opt.value} ${this.formData.currentStatus === opt.value ? 'selected' : ''}"
                    @click="${() => this.handleStatusChange(opt.value)}"
                  >
                    <input
                      type="radio"
                      name="currentStatus"
                      value="${opt.value}"
                      ?checked="${this.formData.currentStatus === opt.value}"
                    />
                    <dees-icon .icon=${this.statusIcons[opt.value]} .iconSize=${20}></dees-icon>
                    <span class="status-label">${opt.label}</span>
                  </label>
                `)}
              </div>
            </div>
          </dees-form>
        </div>

        <div class="form-actions">
          <dees-button type="discreet" @click="${this.handleCancel}" ?disabled="${this.loading}">
            Cancel
          </dees-button>
          <dees-button type="highlighted" @click="${this.handleSave}" ?disabled="${this.loading}">
            ${this.loading ? html`<dees-spinner .size=${16}></dees-spinner>` : ''}
            ${isEdit ? 'Update Monitor' : 'Create Monitor'}
          </dees-button>
        </div>
      </div>
    `;
  }

  private handleNameChange(e: CustomEvent) {
    this.formData = { ...this.formData, name: e.detail };
    if (this.errors.name) {
      this.errors = { ...this.errors, name: '' };
    }
  }

  private handleDisplayNameChange(e: CustomEvent) {
    this.formData = { ...this.formData, displayName: e.detail };
    if (this.errors.displayName) {
      this.errors = { ...this.errors, displayName: '' };
    }
  }

  private handleDescriptionChange(e: CustomEvent) {
    this.formData = { ...this.formData, description: e.detail };
  }

  private handleCategoryChange(e: CustomEvent) {
    this.formData = { ...this.formData, category: e.detail };
  }

  private handleDependenciesChange(e: CustomEvent) {
    const selected = e.detail;
    if (Array.isArray(selected)) {
      this.formData = { ...this.formData, dependencies: selected };
    } else if (selected) {
      // Single selection mode, convert to array
      this.formData = { ...this.formData, dependencies: [selected] };
    }
  }

  private handleStatusChange(status: TStatusType) {
    this.formData = { ...this.formData, currentStatus: status };
  }

  private validate(): boolean {
    const errors: Record<string, string> = {};

    if (!this.formData.name?.trim()) {
      errors.name = 'Name is required';
    } else if (!/^[a-z0-9-]+$/.test(this.formData.name)) {
      errors.name = 'Name must be lowercase letters, numbers, and hyphens only';
    }

    if (!this.formData.displayName?.trim()) {
      errors.displayName = 'Display name is required';
    }

    this.errors = errors;
    return Object.keys(errors).length === 0;
  }

  private handleSave() {
    if (!this.validate()) {
      return;
    }

    this.dispatchEvent(new CustomEvent('monitorSave', {
      detail: { monitor: { ...this.formData } },
      bubbles: true,
      composed: true
    }));
  }

  private handleCancel() {
    this.dispatchEvent(new CustomEvent('monitorCancel', {
      bubbles: true,
      composed: true
    }));
  }

  public reset() {
    this.formData = {
      name: '',
      displayName: '',
      description: '',
      category: '',
      dependencies: [],
      currentStatus: 'operational',
    };
    this.errors = {};
  }

  public setMonitor(monitor: IMonitorFormData) {
    this.formData = { ...monitor };
    this.errors = {};
  }
}
