import { DeesElement, customElement, html, css, cssManager, state, type TemplateResult } from '../plugins.js';
import { deesCatalog } from '../plugins.js';
import { appState, type IAppState, type IContact } from '../state/appstate.js';
import { appRouter } from '../router.js';
import { viewHostCss } from './shared/index.js';
import type { IStatsTile } from '@design.estate/dees-catalog';

@customElement('sipproxy-view-contacts')
export class SipproxyViewContacts extends DeesElement {
  @state() accessor appData: IAppState = appState.getState();
  @state() accessor saving = false;

  public static styles = [
    cssManager.defaultStyles,
    viewHostCss,
    css`
      :host {
        display: block;
        padding: 16px;
      }
      .view-section {
        margin-bottom: 24px;
      }
    `,
  ];

  connectedCallback() {
    super.connectedCallback();
    this.rxSubscriptions.push({
      unsubscribe: appState.subscribe((s) => { this.appData = s; }),
    } as any);
  }

  // ---------- CRUD operations ----------

  private async openAddModal() {
    const { DeesModal } = await import('@design.estate/dees-catalog');

    const formData = { name: '', number: '', company: '', notes: '' };

    await DeesModal.createAndShow({
      heading: 'Add Contact',
      content: html`
        <div style="display:flex;flex-direction:column;gap:12px;padding:4px 0;">
          <dees-input-text
            .label=${'Name'}
            .required=${true}
            .value=${''}
            @input=${(e: Event) => { formData.name = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Number'}
            .required=${true}
            .value=${''}
            @input=${(e: Event) => { formData.number = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Company'}
            .value=${''}
            @input=${(e: Event) => { formData.company = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Notes'}
            .value=${''}
            @input=${(e: Event) => { formData.notes = (e.target as any).value; }}
          ></dees-input-text>
        </div>
      `,
      menuOptions: [
        {
          name: 'Cancel',
          action: async (modal) => { modal.destroy(); },
        },
        {
          name: 'Add Contact',
          action: async (modal) => {
            const name = formData.name.trim();
            const number = formData.number.trim();

            if (!name || !number) {
              deesCatalog.DeesToast.error('Name and number are required', 3000);
              return;
            }

            const newContact: IContact = {
              id: `contact-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
              name,
              number,
              company: formData.company.trim() || undefined,
              notes: formData.notes.trim() || undefined,
            };

            await this.saveContacts([...this.appData.contacts, newContact]);
            modal.destroy();
            deesCatalog.DeesToast.info('Contact added');
          },
        },
      ],
    });
  }

  private async openEditModal(contact: IContact) {
    const { DeesModal } = await import('@design.estate/dees-catalog');

    const formData = {
      name: contact.name,
      number: contact.number,
      company: contact.company || '',
      notes: contact.notes || '',
    };

    await DeesModal.createAndShow({
      heading: 'Edit Contact',
      content: html`
        <div style="display:flex;flex-direction:column;gap:12px;padding:4px 0;">
          <dees-input-text
            .label=${'Name'}
            .required=${true}
            .value=${formData.name}
            @input=${(e: Event) => { formData.name = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Number'}
            .required=${true}
            .value=${formData.number}
            @input=${(e: Event) => { formData.number = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Company'}
            .value=${formData.company}
            @input=${(e: Event) => { formData.company = (e.target as any).value; }}
          ></dees-input-text>
          <dees-input-text
            .label=${'Notes'}
            .value=${formData.notes}
            @input=${(e: Event) => { formData.notes = (e.target as any).value; }}
          ></dees-input-text>
        </div>
      `,
      menuOptions: [
        {
          name: 'Cancel',
          action: async (modal) => { modal.destroy(); },
        },
        {
          name: 'Save Changes',
          action: async (modal) => {
            const name = formData.name.trim();
            const number = formData.number.trim();

            if (!name || !number) {
              deesCatalog.DeesToast.error('Name and number are required', 3000);
              return;
            }

            const updatedContacts = this.appData.contacts.map((c) =>
              c.id === contact.id
                ? { ...c, name, number, company: formData.company.trim() || undefined, notes: formData.notes.trim() || undefined }
                : c,
            );

            await this.saveContacts(updatedContacts);
            modal.destroy();
            deesCatalog.DeesToast.info('Contact updated');
          },
        },
      ],
    });
  }

  private async deleteContact(contact: IContact) {
    const { DeesModal } = await import('@design.estate/dees-catalog');

    await DeesModal.createAndShow({
      heading: 'Delete Contact',
      content: html`
        <p style="color: #e2e8f0; margin: 0 0 8px;">
          Are you sure you want to delete <strong>${contact.name}</strong>?
        </p>
        <p style="color: #94a3b8; font-size: 0.85rem; margin: 0;">
          This action cannot be undone.
        </p>
      `,
      menuOptions: [
        {
          name: 'Cancel',
          action: async (modal) => { modal.destroy(); },
        },
        {
          name: 'Delete',
          action: async (modal) => {
            const updatedContacts = this.appData.contacts.filter((c) => c.id !== contact.id);
            await this.saveContacts(updatedContacts);
            modal.destroy();
            deesCatalog.DeesToast.info('Contact deleted');
          },
        },
      ],
    });
  }

  private async toggleStar(contact: IContact) {
    const updatedContacts = this.appData.contacts.map((c) =>
      c.id === contact.id ? { ...c, starred: !c.starred } : c,
    );
    await this.saveContacts(updatedContacts);
  }

  private async saveContacts(contacts: IContact[]) {
    this.saving = true;
    try {
      const config = await appState.apiGetConfig();
      config.contacts = contacts;
      await appState.apiSaveConfig(config);
    } catch (e: any) {
      deesCatalog.DeesToast.error(`Save failed: ${e.message}`, 4000);
    } finally {
      this.saving = false;
    }
  }

  private getColumns() {
    return [
      {
        key: 'starred',
        header: '',
        sortable: false,
        renderer: (val: boolean | undefined, row: IContact) => {
          const starred = val === true;
          return html`
            <span
              style="cursor:pointer;font-size:1.2rem;color:${starred ? '#fbbf24' : '#475569'};transition:color 0.15s;"
              @click=${(e: Event) => { e.stopPropagation(); this.toggleStar(row); }}
            >${starred ? '\u2605' : '\u2606'}</span>
          `;
        },
      },
      {
        key: 'name',
        header: 'Name',
        sortable: true,
      },
      {
        key: 'number',
        header: 'Number',
        renderer: (val: string) =>
          html`<span style="font-family:'JetBrains Mono',monospace;font-size:.85rem;letter-spacing:.02em">${val}</span>`,
      },
      {
        key: 'company',
        header: 'Company',
        renderer: (val: string | undefined) => val || '-',
      },
      {
        key: 'notes',
        header: 'Notes',
        renderer: (val: string | undefined) =>
          html`<span style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;color:#94a3b8" title=${val || ''}>${val || '-'}</span>`,
      },
    ];
  }

  private getDataActions() {
    return [
      {
        name: 'Call',
        iconName: 'lucide:phone' as any,
        type: ['inRow'] as any,
        actionFunc: async ({ item }: { item: IContact }) => {
          appState.selectContact(item);
          appRouter.navigateToView('telephony', 'phone');
        },
      },
      {
        name: 'Star',
        iconName: 'lucide:star' as any,
        type: ['inRow'] as any,
        actionFunc: async ({ item }: { item: IContact }) => {
          await this.toggleStar(item);
        },
      },
      {
        name: 'Edit',
        iconName: 'lucide:pencil' as any,
        type: ['inRow'] as any,
        actionFunc: async ({ item }: { item: IContact }) => {
          await this.openEditModal(item);
        },
      },
      {
        name: 'Delete',
        iconName: 'lucide:trash2' as any,
        type: ['inRow'] as any,
        actionFunc: async ({ item }: { item: IContact }) => {
          await this.deleteContact(item);
        },
      },
      {
        name: 'Add Contact',
        iconName: 'lucide:plus' as any,
        type: ['header'] as any,
        actionFunc: async () => {
          await this.openAddModal();
        },
      },
    ];
  }

  // ---------- Render ----------

  public render(): TemplateResult {
    const contacts = this.appData.contacts || [];
    const companies = new Set(
      contacts.map((c) => c.company?.trim()).filter((c) => c && c.length > 0),
    );

    const tiles: IStatsTile[] = [
      {
        id: 'total',
        title: 'Total Contacts',
        value: contacts.length,
        type: 'number',
        icon: 'lucide:contactRound',
        description: contacts.length === 1 ? '1 contact' : `${contacts.length} contacts`,
      },
      {
        id: 'starred',
        title: 'Starred',
        value: contacts.filter((c) => c.starred).length,
        type: 'number',
        icon: 'lucide:star',
        color: 'hsl(45 93% 47%)',
        description: 'Quick-dial contacts',
      },
      {
        id: 'companies',
        title: 'Companies',
        value: companies.size,
        type: 'number',
        icon: 'lucide:building2',
        description: `${companies.size} unique`,
      },
    ];

    return html`
      <dees-heading level="3">Contacts</dees-heading>

      <div class="view-section">
        <dees-statsgrid .tiles=${tiles} .minTileWidth=${220} .gap=${16}></dees-statsgrid>
      </div>

      <div class="view-section">
        <dees-table
          heading1="Contacts"
          heading2="${contacts.length} total"
          dataName="contacts"
          .data=${this.sortedContacts(contacts)}
          .rowKey=${'id'}
          .searchable=${true}
          .columns=${this.getColumns()}
          .dataActions=${this.getDataActions()}
        ></dees-table>
      </div>
    `;
  }

  private sortedContacts(contacts: IContact[]): IContact[] {
    return [...contacts].sort((a, b) => {
      if (a.starred && !b.starred) return -1;
      if (!a.starred && b.starred) return 1;
      return a.name.localeCompare(b.name);
    });
  }
}
